使用符号栈和数值栈,在当前符号优先级高于栈顶符号时进栈,优先级等于和小于时出栈执行计算。左括号必须进栈,但优先级设置为最低,右括号必出栈直到对应的左括号出栈。
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
void pop_and_cal(vector<int> &values, vector<char> &ops) {
char op = ops.back();
ops.pop_back();
int num2 = values.back();
values.pop_back();
int num1 = values.back();
values.pop_back();
int result = 0;
switch(op) {
case '+': result = num1 + num2; break;
case '-': result = num1 - num2; break;
case '*': result = num1 * num2; break;
case '/': result = num1 / num2; break;
}
values.push_back(result);
}
// 处理正负号,统一括号
string preprocess(string line) {
stringstream ss;
bool last_is_value = false;
for(char c : line) {
// 给正负号前加一个数字0
if (!last_is_value
&& (c == '-' || c == '+')) {
ss << 0;
}
// 替换括号
switch(c) {
case '[':
case '{': c = '('; break;
case ']':
case '}': c = ')'; break;
}
if ((c >= '0' && c <= '9')
|| c == ')') {
last_is_value = true;
} else {
last_is_value = false;
}
ss << c;
}
return ss.str();
}
int cal(string &raw_exp) {
int prior[128] = {0};
vector<int> values;
vector<char> ops;
string exp = preprocess(raw_exp);
prior['('] = 0;
prior[')'] = 0;
prior['+'] = 10;
prior['-'] = 10;
prior['*'] = 20;
prior['/'] = 20;
int state = 0;
int i = 0;
while(i < exp.size()) {
char c = exp[i];
if ( c >= '0' && c <= '9') {
int value;
stringstream ss;
// 读取数字的所有位
while(i < exp.size()) {
c = exp[i];
if ( c < '0' || c > '9') {
break;
}
ss << c;
i++;
}
ss >> value;
values.push_back(value);
}
if (i >= exp.size()) break;
if (c == ')') {
while(ops.back() != '(') {
pop_and_cal(values, ops);
}
ops.pop_back();
} else if(c == '(') {
ops.push_back(c);
} else {
while (ops.size() > 0 && prior[c] <= prior[ops.back()]) {
pop_and_cal(values, ops);
}
ops.push_back(c);
}
i++;
}
while(ops.size() > 0) pop_and_cal(values, ops);
return values.back();
}
int main() {
string line;
while(getline(cin, line)) {
cout << cal(line) << endl;
}
} 
京公网安备 11010502036488号