题目:https://leetcode.cn/problems/basic-calculator/submissions/
非常经典的题目,一定一定要熟记!一些要点是
- 优先级处理符号
- 预处理删除空格,补零
- while循环内,根据优先级分为3种情况
- 结束后,运算符栈一定为空
class Solution {
public:
// 双栈,数字栈,操作数栈
stack<int> num_stk;
stack<char> op_stk;
// 确定优先级,栈内优先级,栈外优先级
int inprior(char op) {
int p;
switch (op) {
case '#': p = 0; break;
case '+':
case '-': p = 3; break;
case '*':
case '/': p = 5; break;
case '(': p = 1; break;
case ')': p = 6; break;
}
return p;
}
int outprior(char op) {
int p;
switch (op) {
case '#': p = 0; break;
case '+':
case '-': p = 2; break;
case '*':
case '/': p = 4; break;
case '(': p = 6; break;
case ')': p = 1; break;
}
return p;
}
// 单次计算
void calc() {
char op = op_stk.top();
op_stk.pop();
int num2 = num_stk.top();
num_stk.pop();
int num1 = num_stk.top();
num_stk.pop();
int res;
switch (op) {
case '+': res = num1 + num2; break;
case '-': res = num1 - num2; break;
case '*': res = num1 * num2; break;
case '/': res = num1 / num2; break;
default: break;
}
num_stk.push(res);
}
// 判断数字
bool isnum(char ch) {
return ch >= '0' && ch <= '9';
}
// 预处理:删除空格,遇到单元操作时,在前面补零。
string preprocess(string s) {
int k;
while ((k = s.find(" ")) != -1) {
s.replace(k, 1, "");
}
if (s[0] == '-' || s[0] == '+') {
s.insert(0, "0");
}
while ((k = s.find("(-")) != -1) {
s.insert(k+1, "0");
}
while ((k = s.find("(+")) != -1) {
s.insert(k+1, "0");
}
return s;
}
int calculate(string s) {
op_stk.push('#');
s = preprocess(s);
s += '#';
int len = s.length();
int num = 0;
for (int i = 0; i < len; i++) {
char ch = s[i];
// 连续字符处理
if (isnum(ch)) {
num = num * 10 + (ch - '0');
if (!isnum(s[i+1])) {
num_stk.push(num);
num = 0;
}
}
else {
while (true) {
if (inprior(op_stk.top()) > outprior(ch)) {
calc();
}
else if (inprior(op_stk.top()) < outprior(ch)) {
op_stk.push(ch);
break;
}
// 两种情况:栈内是'(',栈外是')';栈内外都是'#'
else {
op_stk.pop();
break;
}
}
}
}
// 这里符号栈一定是空
return num_stk.top();
}
};