227. 基本计算器 II
实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。
示例 1:
输入: "3+2*2"
输出: 7
解析
基本思路就是我们把所有的运算都转化为加法,把值放入栈中,然后再统一出栈加起来。
class Solution {
public int calculate(String s) {
/*
将 减法、乘法、除法 转换为 加法
某个数 num, 如果前面的对应的运算符是 -,那么 将 -num 压入栈中
这样,我们只需在最后将栈的元素全部弹出,完成加法操作,即可得到最终结果
对于括号,它存在递归性质
即
3 * (2 + 4 * 3) + 2
= 3 * calculate(2 + 4 * 3) + 2
= 3 * 24 + 2
即我们可以将括号内的字符串当作一个运算式,再递归调用本函数,最终返回一个数值
*/
int[] i = new int[1];
return dfs(s, i);
}
private int dfs(String s, int[] i){
Deque<Integer> stack = new LinkedList<>();
//记录某个连续的数,比如 "42",那么我们首先 num = 4,然后遇到 2 ,num = num * 10 + 2 = 42
int num = 0;
char op = '+';
for(; i[0] < s.length(); i[0]++){
char ch = s.charAt(i[0]);
//遇到左括号,递归运算内部子式
if(ch == '('){
++i[0];
num = dfs(s, i);
}
if(Character.isDigit(ch)){
num = num * 10 + (ch - '0');
}
//不是数字,不是空格(运算符 或 '(' 或 ')' ) 或者 到了最后一个字符,那么根据前面记录的 op 操作符 将数字压栈,然后将新的运算符 ch 赋值给 op
if(!Character.isDigit(ch) && ch != ' ' || i[0] == s.length() - 1){
switch(op){
case '+':
stack.push(num); break;
case '-':
stack.push(-num); break;
case '*':
int pre = stack.pop();
stack.push(pre * num);
break;
case '/':
pre = stack.pop();
stack.push(pre / num);
break;
}
num = 0;
op = ch;
}
/*
遇到右括号,退出循环,然后计算结果, 返回上一层 dfs
这一步写在最后是因为,当 ch 为 右括号 时,那么我们需要先将前面已经得到的 num 压入栈中,再退出循环
*/
if(ch == ')'){
break;
}
}
int res = 0;
while(!stack.isEmpty()){
res += stack.pop();
}
return res;
}
}
注意:本文归作者所有,未经作者允许,不得转载