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.
Example 1:
Input: "3+2*2"
Output: 7
Example 2:
Input: " 3/2 "
Output: 1
Example 3:
Input: " 3+5 / 2 "
Output: 5
Note:
- You may assume that the given expression is always valid.
- Do not use the
eval
built-in library function.
思路:
解法1
我们是如同第224题,通过使用两个stack来分别存放数字和符号,但是因为乘除的优先级高于加减,所有我们先处理乘除,然后再处理加减。
class Solution {
public:
int calculate(string s) {
list<int> nums, signs;
for (int i = 0; i<int(s.size()); i++) {
if (isdigit(s[i])) {
nums.push_back(getNext(s, i));
}
else if (s[i] == '-') signs.push_back(-1);
else if (s[i] == '+') signs.push_back(1);
else if (s[i] == '*') {
while (!isdigit(s[i])) i++;
nums.back() *= getNext(s, i);
}
else if (s[i] == '/') {
while (!isdigit(s[i])) i++;
nums.back() /= getNext(s, i);
}
}
int sum = 0;
signs.push_front(1);
list<int>::iterator itNum = nums.begin(), itSign = signs.begin();
while (itNum != nums.end()) {
sum += (*itNum) * (*itSign);
itNum++;itSign++;
}
return sum;
}
private:
int getNext(const string& s, int& i) {
string numS;
while (isdigit(s[i])) {
numS += s[i++];
}
i--;
return stoi(numS);
}
};
解法2:
我们每次都将操作符之前的一个数和操作符存下来,这样当我们遇到乘除运算的时候可以优先处理,也可以一次处理完所有的数据。
class Solution {
public:
int calculate(string s) {
long pre = 0, sum = 0, curr = 0;
char opt = '+';
int n = int(s.size());
for (int i = 0; i < n; i++) {
if (isdigit(s[i])) {
curr = curr * 10 + s[i] - '0';
}
if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || i == n-1) {
switch (opt) {
case '+': pre += curr; break;
case '-': pre -= curr; break;
case '*': pre *= curr; break;
case '/': pre /= curr; break;
default: break;
}
if (s[i] == '-' || s[i] == '+' || i == n - 1) {
sum += pre;
pre = 0;
}
curr = 0;
opt = s[i];
}
}
return int(sum);
}
};