首先要做的是:中缀表达式转换为后缀表达式!
算法:
中缀表达式转后缀表达式的方法:
1.遇到操作数:直接输出(添加到后缀表达式中)
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈(如果此时的符号优先级小于等于栈顶的,则一直弹出,谈到遇到左括号或者遇到高优先级的符号或者栈空了)
6.最终将栈中的元素依次出栈,输出。
根据输入要求,输入为字符串,里面有数字(有负数)、符号、括号:
string tmp; for (int i = 0; i < str.size(); i++) { if (shuzi(str[i])) { tmp += str[i]; } else { if (tmp != "") { v.push_back(tmp); tmp = ""; } v.push_back(str.substr(i, 1)); } } if (tmp != "") v.push_back(tmp); for (int i = 0; i < v.size(); i++) { if (v[i] == "-") { if (i - 1 >= 0 && !shuzi(v[i - 1][0])) { v.insert(v.begin() + i, "0"); } else { if (i == 0) { v.insert(v.begin() + i, "0"); } } } }
第一步先根据运算符来分割字符串。然后如果有负数会出现负号前面没有数字的情况,我们在负号前面补0。
以上是字符串分割部分。
接下来是专为后缀表达式的部分:
for (int i = 0; i < v.size(); i++) { if (shuzi(v[i][0]))//number { hs.push_back(v[i]); } else//symbol { if (s.empty()) { s.push(v[i]); } else { if (v[i] == "(") { s.push(v[i]); } else if (v[i] == ")") { while (s.top() != "(") { hs.push_back(s.top()); s.pop(); } s.pop(); } else if (v[i] == "[") { s.push(v[i]); } else if (v[i] == "]") { while (s.top() != "[") { hs.push_back(s.top()); s.pop(); } s.pop(); } else if (v[i] == "{") { s.push(v[i]); } else if (v[i] == "}") { while (s.top() != "{") { hs.push_back(s.top()); s.pop(); } s.pop(); } else { while ((!s.empty()) && (fuhao(v[i]) <= fuhao(s.top())) && (s.top() != "("&&s.top() != "["&&s.top() != "{")) { hs.push_back(s.top()); s.pop(); } s.push(v[i]); } } } } while (!s.empty()) { hs.push_back(s.top()); s.pop(); } //以上为后缀表达式
这是根据上面算法来的。注意那一步,要把s.empty放在前面,如果前面是假后面就不判断了。这很关键,否则还会报错。
最后就是根据后缀表达式来计算了:
遇到符号就弹出两个数,先弹出来的是左操作数,后弹出的是右操作数。
计算完后再压进去。
最后栈顶的数就是结果。
总的代码:
#include <stdio.h> #include <iostream> #include <stack> #include <string> #include <vector> using namespace std; bool shuzi(char s) { return s >= '0'&&s <= '9'; } int fuhao(string s) { if (s[0] == '+') return 0; if (s[0] == '-') return 0; if (s[0] == '*') return 1; if (s[0] == '/') return 1; if (s[0] == '(') return 4; if (s[0] == ')') return 5; if (s[0] == '{') return 6; if (s[0] == '}') return 7; } int main() { string str; while (cin >> str) { //str = "9*(4+5)"; stack<string> s; stack<int> s1; vector<string> hs; vector<string> v; string tmp; for (int i = 0; i < str.size(); i++) { if (shuzi(str[i])) { tmp += str[i]; } else { if (tmp != "") { v.push_back(tmp); tmp = ""; } v.push_back(str.substr(i, 1)); } } if (tmp != "") v.push_back(tmp); for (int i = 0; i < v.size(); i++) { if (v[i] == "-") { if (i - 1 >= 0 && !shuzi(v[i - 1][0])) { v.insert(v.begin() + i, "0"); } else { if (i == 0) { v.insert(v.begin() + i, "0"); } } } } for (int i = 0; i < v.size(); i++) { if (shuzi(v[i][0]))//number { hs.push_back(v[i]); } else//symbol { if (s.empty()) { s.push(v[i]); } else { if (v[i] == "(") { s.push(v[i]); } else if (v[i] == ")") { while (s.top() != "(") { hs.push_back(s.top()); s.pop(); } s.pop(); } else if (v[i] == "[") { s.push(v[i]); } else if (v[i] == "]") { while (s.top() != "[") { hs.push_back(s.top()); s.pop(); } s.pop(); } else if (v[i] == "{") { s.push(v[i]); } else if (v[i] == "}") { while (s.top() != "{") { hs.push_back(s.top()); s.pop(); } s.pop(); } else { while ((!s.empty()) && (fuhao(v[i]) <= fuhao(s.top())) && (s.top() != "("&&s.top() != "["&&s.top() != "{")) { hs.push_back(s.top()); s.pop(); } s.push(v[i]); } } } } while (!s.empty()) { hs.push_back(s.top()); s.pop(); } //以上为后缀表达式 for (int i = 0; i < hs.size(); i++) { if (!shuzi(hs[i][0])) { int l = s1.top(); s1.pop(); int r = s1.top(); s1.pop(); if (hs[i][0] == '+') { s1.push(l + r); } if (hs[i][0] == '-') { s1.push(r - l); } if (hs[i][0] == '*') { s1.push(l * r); } if (hs[i][0] == '/') { s1.push(r / l); } } else { s1.push(atoi(hs[i].c_str())); } } cout << s1.top() << endl; int kk = 0; } return 0; }