题目
Implement a basic calculator to evaluate a simple expression string.
The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero.
You may assume that the given expression is always valid.
Some examples:
"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5
Note: Do not use the eval built-in library function.
题意
实现一个简单的计算器,输入一个字符串,输出其结果。字符串只包含非负整数、+、 -、 *、 / 操作符以及空格。整数除法不包括0,你可以假设给出的表达式总是合法的。以下是一些例子
"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5
注意:不要使用内置库函数eval
分析
首先要注意,这里的calculator包含了加减乘除四种运算,这里涉及到优先级的问题,还有空格的问题。
我模拟了人的大脑的运算规则,先算优先级高的部分,再算优先级低的部分,对于式子3+2*2
,我们会先算出2*2 = 4
,然后 3+4=7
。对于长一点的式子同理。
我的解法是,遍历一遍表达式,遇到 + -
且后面紧跟着的不是 ‘* /’ ,直接计算, 遇到 * /
先计算这个部分的结果,再和前面的合并。
#代码
int calculate(string s) {
// num 运算符分开的每个数
// result 结果
// curr 高阶运算符(* /)部分的计算结果
// lastOp 高阶运算符(* /)部分的前面的运算符,
// 当前num和前一个num之间的运算符,0表示未初始化,1、2、3、4分别表示加减乘除
int num = 0,result=-1,curr = 0,lastOp=0,op=0, i;
for (i = 0; i < s.size(); i++) {
if (s[i] >= '0' && s[i] <= '9') {
num = num * 10 + s[i] - '0';
}
if(s[i] == '+'|| s[i] == '-' || s[i] == '*' || s[i] == '/' || i==s.size()-1){
switch (op) {
case 0:
result = num;
curr = num;
break;
case 1: case 2:
if (s[i] != '*' && s[i] != '/')
result = (op == 1 ? result + num : result - num);
else {
curr = num;
lastOp = op;
}
break;
case 3: case 4:
curr = op == 3 ? curr* num : curr / num;
if (s[i] == '+' || s[i] == '-' || i == s.size() - 1) {
if (lastOp == 1)
result += curr;
else if (lastOp == 2)
result -= curr;
else
result = curr;
lastOp = 0;
}
break;
}
num = 0;
op = s[i] == '+' ? 1 : s[i] == '-' ? 2 : s[i] == '*' ? 3 : s[i] == '/' ? 4 : 0;
}
}
return result;
}
代码的时间复杂度是O(n),空间复杂度为O(1),
109 / 109 test cases passed.
Runtime: 13 ms