题目
思路
- 本质就是模拟四则运算
- 需要维护两个栈,
op
放操作符,nn
放数字,无论什么操作,一定是1个操作符匹配2个数字,所以说,独立出来的运算函数一定是简单的,操作符栈顶弹1个,数字栈顶弹2个,算完了再压进去。 - 如何维护括号的优先级,遇到左括号直接压栈,遇到右括号就一直操作直到左括号。这一步很关键,体现了“局部优先”的思想。
-
代码
class Solution {
public:
void calcu(stack<char>& op, stack<int>& nn) {
if (op.empty() || nn.empty()) {
return;
}
char cur_op = op.top();
op.pop();
if (cur_op == '(') {
return;
}
int num_behind = nn.top();
nn.pop();
int num_forward = nn.top();
nn.pop();
int res_num = 0;
if (cur_op == '*') {
res_num = num_forward * num_behind;
} else if (cur_op == '+') {
res_num = num_forward + num_behind;
} else if (cur_op == '-') {
res_num = num_forward - num_behind;
} else if (cur_op == '/') {
res_num = num_forward / num_behind;
}
nn.push(res_num);
}
int calculate(string s) {
stack<char> op;
stack<int> nn;
map<char, int> h = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
int len_s = s.size();
for (int i = 0; i < len_s; ++i) {
if (s[i] == ' ') {
continue;
}
if (isdigit(s[i])) {
int j = i + 1, num = int (s[i] - '0');
while (j < len_s && isdigit(s[j])) {
num *= 10;
num += int (s[j] - '0');
j++;
}
nn.push(num);
i = j - 1;
} else if (s[i] == '(') {
op.push(s[i]);
} else if (s[i] == ')') {
while (!op.empty() && op.top() != '(') {
calcu(op, nn);
}
// 左括号也要出栈
op.pop();
} else {
// 低优先级入栈需要先将高优先级弹栈
while (!op.empty() && h[op.top()] >= h[s[i]]) {
cout << s[i] << endl;
calcu(op, nn);
}
op.push(s[i]);
}
}
while (!op.empty()) {
calcu(op, nn);
}
return nn.top();
}
};