题目链接
题目解析
把字符串里面的数字和字符提取出来,进行运算,然后返回运算结果
算法原理
表达式求值->用栈来解决
法一:用栈来模拟计算过程, 一个栈来维护数,另一个用变量来维护操作符, +为初始运算符
碰到一个数,如果运算符是+就先放进去
继续往后走,遇到其它运算符就直接更新运算符
如果是减号, 就把负数放进栈里面, 为了让栈里面的数后面直接都进行加法运算
遇到*,/优先级是最高的, 因此就直接进行出栈,然后运算,再入栈
然后遇到一个大于一位的数,那么使用一个tmp来进行接受第一个数, 如果第二个字符还是数, 那么 就把tmp里面的值10+第二个字符的数(tmp*10+这个数)
'
当字符串遍历结束之后, 我们把栈里面的元素全都进行一次加法运算
总结:
1. 遇到操作符: 更新操作符 op
2. 遇到数字:
1> 先把数字提取出来, tmp;
2> 分情况讨论, 根据 op 的符号
1) op == '+' , tmp 直接入栈
2) op == '-' ,-tmp 入栈
3) op == '*', 直接乘到栈顶元素上
4) op == '/', 直接除到栈顶元素上
不需要用双栈的原因: 知道了操作符的优先级, 因此不需要用双栈, 直接用一个字符保存操作符即可
法二: 中缀表达式转化为后缀表达式
代码编写
class Solution {
public int calculate(String ss) {
char[] s = ss.toCharArray();
//创建俩个栈
//记录数
Stack<Integer> stack = new Stack<>();
//记录操作符
char op = '+';
//遍历字符串
for (int i = 0; i < s.length;) {
//处理空格
if (s[i] == ' ') {
i++;
} else if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') {
//分情况讨论
//如果是操作符: 更新操作符op
op = s[i];
i++;
} else {
//如果是数字
int tmp = 0;
while (i < s.length && s[i] >= '0' && s[i] <= '9') {
tmp = tmp * 10 + (s[i] - '0');
i++;
}
//分情况讨论
if (op == '+') {
//直接入栈
stack.push(tmp);
} else if (op == '-') {
stack.push(-tmp);
} else if (op == '*') {
//直接和栈顶元素相乘
int rs = stack.pop();
stack.push(rs * tmp);
} else {
//直接和栈顶元素相除
int rs = stack.pop();
stack.push(rs / tmp);
}
}
}
//把栈里面的元素都加在一起
int ans = 0;
//先记录下来stack的长度, 不然后面长度会根据栈的变化而变化
while (!stack.isEmpty()) {
ans += stack.pop();
}
return ans;
}
}
注意:
1> 要处理空格, 遇到空格往后走一位
2> 最后处理结果的时候如果采用for, 我们要提前记录下来栈的大小, 不然栈会随着栈的变化,大小也跟着变