实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 。
示例 1:
输入: "1 + 1"
输出: 2
示例 2:
输入: " 2-1 + 2 "
输出: 3
示例 3:
输入: "(1+(4+5+2)-3)+(6+8)"
输出: 23
做法: 传统的《数据结构》介绍的方法,单调栈法
几个注意点:
1.单调栈应严格单调
2.如果当前op的优先级小于栈顶的op的优先级,应使得栈顶元素出栈直到栈顶元素优先级小于当前op的优先级,但是如果栈顶是'('的话,就可以插入了,不能再把'('给出栈了,因为栈内'('的优先级最小,栈外最大
3.注意和栈顶元素比较的时候,要判断栈是不是空的
class Solution {
public:
stack<int> nums;
stack<char> ops;
int ans = 0;
int in_level(char op){
if (op == '+')
return 2;
if (op == '-')
return 3;
if (op == '(')
return 1;
if (op == '*')
return 4;
if (op == '/')
return 5;
return 0;
}
int out_level(char op){
if (op == '+')
return 2;
if (op == '-')
return 3;
if (op == '(')
return 6;
if (op == '*')
return 4;
if (op == '/')
return 5;
return 0;
}
int calculate(string s){
string str = "";
for (auto x:s){
if (x != ' ')
str += x;
}
for (int i = 0; i < str.size(); ++i){
if (str[i] >= '0' && str[i] <= '9'){
int j = i,sum = 0;
while (str[j] >= '0' && str[j] <= '9'){
sum = sum * 10 + (str[j] - '0');
++j;
}
nums.push(sum);
i = j - 1;
}
else{
if (str[i] == ')'){
while(ops.top() != '('){
int num2 = nums.top();
nums.pop();
int num1 = nums.top();
nums.pop();
char opp = ops.top();
ops.pop();
if (opp == '+') nums.push(num1 + num2);
if (opp == '-') nums.push(num1 - num2);
if (opp == '*') nums.push(num1 * num2);
if (opp == '/') nums.push(num1 / num2);
}
ops.pop();
}
else if (ops.empty() || out_level(str[i]) > in_level(ops.top())){
ops.push(str[i]);
}
else if (out_level(str[i]) <= in_level(ops.top())){
while(ops.size() > 0 && out_level(str[i]) <= in_level(ops.top())){
int num2 = nums.top();
nums.pop();
int num1 = nums.top();
nums.pop();
char opp = ops.top();
ops.pop();
if (opp == '+') nums.push(num1 + num2);
if (opp == '-') nums.push(num1 - num2);
if (opp == '*') nums.push(num1 * num2);
if (opp == '/') nums.push(num1 / num2);
}
ops.push(str[i]);
}
}
}
while(ops.size() > 0){
int num2 = nums.top();
nums.pop();
int num1 = nums.top();
nums.pop();
char opp = ops.top();
ops.pop();
if (opp == '+') nums.push(num1 + num2);
if (opp == '-') nums.push(num1 - num2);
if (opp == '*') nums.push(num1 * num2);
if (opp == '/') nums.push(num1 / num2);
}
return nums.top();
}
};