题目
实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。
示例 1:
输入: “3+2*2”
输出: 7
示例 2:
输入: " 3/2 "
输出: 1
示例 3:
输入: " 3+5 / 2 "
输出: 5
说明:
- 你可以假设所给定的表达式都是有效的。
- 请不要使用内置的库函数 eval。
解答
思想就是:减当加算,乘除直接算。
要点如下:
- 将减法转化为加法(其实就是加负数)。
- 乘除法优先级高,直接计算。
- 整数可能由多位组成。
- 表达式中没有括号,所以优先级顺序不会改变。
减法为什么要当加法算呢?
因为栈的计算过程相当于倒着算,那么前面的减法就相当于 - (后面的运算结果了)。
举个例子:
"1 * 2 - 3 / 4 + 5 * 6 - 7 * 8 + 9 / 10"
输出:
28
预期:
-24
这种情况如果按减法运算相当于这样加括号运算:1 * 2 - ( 3 / 4 + 5 * 6 - ( 7 * 8 + 9 / 10)) 。
解括号之后:1 * 2 - 3 / 4 - 5 * 6 + 7 * 8 - 9 / 10 = 28。
这样运算结果就会出错误了,所以减法最好转化成加相反数的方式来运算。
代码
class Solution {
public int calculate(String s) {
LinkedList<Integer> nums = new LinkedList<>();
int res = 0;
int d = 0;
char preSign = '+';
for(int i = 0; i < s.length(); i ++) {
char ch = s.charAt(i);
if(ch >= '0') {
d = d * 10 + s.charAt(i) - '0';
}
if((ch < '0' && ch != ' ') || i == s.length() - 1) {
if(preSign == '+') {
nums.push(d);
} else if(preSign == '-') {
nums.push(-d);
} else {
int temp = preSign == '*' ? nums.peek() * d : nums.peek() / d;
nums.pop();
nums.push(temp);
}
preSign = ch;
d = 0;
}
}
while(!nums.isEmpty()) {
res += nums.pop();
}
return res;
}
}