题目:
Implement a basic calculator to evaluate a simple expression string.
The expression string may contain open (
and closing parentheses )
,
the plus +
or minus sign -
, non-negative integers
and empty spaces .
The expression string contains only non-negative integers, +
, -
, *
, /
operators
, open (
and closing parentheses )
and
empty spaces . The integer division should truncate toward zero.
You may assume that the given expression is always valid. All intermediate results will be in the range of [-2147483648,
2147483647]
.
Some examples:
"1 + 1" = 2 " 6-4 / 2 " = 4 "2*(5+5*2)/3+(6/2+8)" = 21 "(2+6* 3+5- (3*14/7+2)*5)+3"=-12
Note: Do not use the eval
built-in
library function.
思路:
我们顺序循环,处理字符串中的各个字符:如果遇到‘+’或者‘-’,就将其加入到数组nums中;如果遇到‘*’或者‘/’,则直接进行计算;如果遇到'(',则递归调用parseExpr函数,返回括号对里面的计算结果。当所有的数都计算完毕之后,将数组nums中的所有数加起来,返回和就可以了。
这里的奥妙在于采用"pass by reference"的方法,使得i成为“全局变量”;另外就是合理地设计递归调用的函数,以处理括号嵌套的问题。
代码:
class Solution {
public:
int calculate(string s) {
int i = 0;
return parseExpr(s, i);
}
private:
int parseExpr(string &s, int &i) { // parse the expression
vector<int> nums;
char op = '+';
int n;
for (; i < s.length() && op != ')'; ++i) {
if (s[i] == ' ') {
continue;
}
if (s[i] == '(') {
n = parseExpr(s, ++i);
}
else {
n = parseNum(s, i);
}
switch(op) {
case '+':
nums.push_back(n);
break;
case '-':
nums.push_back(-n);
break;
case '*':
nums.back() *= n;
break;
case '/':
nums.back() /= n;
break;
}
op = s[i];
}
int res = 0;
for (int n : nums) {
res += n;
}
return res;
}
int parseNum(string &s, int &i) { // parse the num
int n = 0;
while (i < s.length() && isdigit(s[i])) {
n = 10 * n + s[i++] - '0';
}
return n;
}
};