Basic Calculator
这题看起来很简单,但其实要注意的是虽然只有加减法,计算顺序不是很重要,但是括号也不是没有意义的,如果括号前面是个减法,那么括号里的符合是需要反转的。
处理好这一点那么这题应该就没什么问题了。
如果把括号里的结果当成一个数那么整个算式就变成顺序了加减法了,而实际上括号里的实际上也是一个顺序的加减法而已。
对于顺序的加减法我们只需要顺序累加即可:res = res + op*num 其中res为已经计算好的结果,num为下一次要计算的数值,op则是+或者-(用1、-1表示)
而遇到左括号时,我们暂时将已算好的数值存到栈中,同时也要把括号前的计算符号op存起来。然后括号里的内容其实就是顺序的加减法了,套用上一步,直到遇到右括号。遇到右括号表示我们已经算出了括号里的值。
那么现在只需要把这个括号等效为一个值,再把之前存的值与符号拿出来做计算就完成了这个括号的计算。
这里用栈存的原因是它采用先进后出的规则,实际中我们往往会遇到括号的嵌套使用,那么显然越里面的括号是越优先计算的。
简单例子:
1+(1-2-(3+4))
首先默认op为1(因为数字都是正数),res=0,stack<int> nums
读入num = 1,res = res + op * num = 0 + 1*1 = 1
读入op = 1 (+)
读入(,存res与op,此时栈中nums:1,1。第二个1为op。将res与op还原初始值。
读入num = 1,res = res + op * num = 0 + 1*1 = 1
读入op = -1 (-)
读入num = 2,res = res + op * num = 1 + (-1)*2 = -1
读入op = -1 (-)
读入(,存res与op,此时栈中nums:1,1,-1,-1。第二个-1为op,将res与op还原初始值。
读入num = 3,res = res + op * num = 0 + 1*3 = 3
读入op = 1 (+)
读入num = 4,res = res + op * num = 3 + 1*4 = 7
读入),取出栈顶的res与op,然后把它们出栈,记为res1与op1,res = res1 + op1*res = -1 + (-1)*7 = -8.此时栈中nums:1,1。
读入),取出栈顶的res与op,然后把它们出栈,记为res1与op1,res = res1 + op1*res = 1 + 1*(-8) = -7.此时栈中nums:(空)。
按照这个思路即可完成代码。
class Solution {
public:
int calculate(string s) {
stack<int> nums;
int op = 1;
int res = 0;
for(int i = 0; i < s.size(); i++){
if(isdigit(s[i])){
int num = 0;
while(isdigit(s[i])){
<span style="white-space:pre"> </span>num = num*10 + (s[i]-'0');
<span style="white-space:pre"> </span>i++;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>res = res + num*op;
}
if(s[i] == '+')
op = 1;
if(s[i] == '-')
op = -1;
if(s[i] == '('){
nums.push(res);
nums.push(op);
res = 0;op = 1;
}
if(s[i] == ')'){
op = nums.top();
nums.pop();
res = nums.top() + op * res;
nums.pop();
op = 1;
}
}
return res;
}
};
class Solution {
public:
int calculate(string s) {
stack<int> nums;
char op = '+';
int num = 0;
for(int i = 0; i < s.size(); i++){
if(isdigit(s[i])){
num = num*10 + (s[i]-'0');
}
if(!isdigit(s[i]) && s[i] != ' ' || i+1 == s.size()){
if(op == '+')
nums.push(num);
else if(op == '-')
nums.push(-num);
else if(op == '*'){
int temp = nums.top() * num;
nums.pop();
nums.push(temp);
}
else if(op == '/'){
int temp = nums.top() / num;
nums.pop();
nums.push(temp);
}
num = 0;
op = s[i];
}
}
int result = 0;
while(!nums.empty()){
result += nums.top();
nums.pop();
}
return result;
}
};
编程中需要注意的就是最后一个数也要加入计算。