227 Basic Calculator II
链接:https://leetcode.com/problems/basic-calculator-ii/
问题描述:
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.
Credits:
Special thanks to @ts for adding this problem and creating all test cases.
Hide Tags String
这是一体计算表达式的问题。下面我描述下我的解决方法。代码中我需要两个栈帮,一个栈放数字,另一个栈放运算符,还需要一个int变量。
stack<int> num;
stack<char> oper;
int temp=0;
1 去掉输入string中的空格;
2 开始遍历表达式
2.1如果遇到表达式‘(’,那么直接压栈。
2.2如果遇到‘*’或者‘/’。
2.2.1如果oper栈为空则将temp压入栈中,碰到的运算符也压入栈中。
2.2.2如果oper不为空,且oper.top()=='*'||oper.top()=='/',那么让temp和num.top()做相
应的计算,结果保存到temp中。num删除最后一个元素。将temp压栈,碰到的运算符压栈。
2.3如果遇到‘+’或者‘-’。
2.3.1如果oper栈为空则将temp压入栈中,碰到的运算符也压入栈中。
2.3.2如果oper不为空,且oper.top()=='*'||'/'||‘+’||‘-’,那么让temp和num.top()做相
应的计算,结果保存到temp中。num删除最后一个元素。将temp压栈,碰到的运算符压栈。
2.4如果遇到‘)’。那么检查oper.top()是不是‘(’,如果不是,则做相关计算结果保存在temp中,num删
除最后一个元素,oper删除最后一个元素。循环检查,当oper.top()是‘(’时删除‘(’。
3 结束表达式的遍历后,检查oper是否为空。如果不为空则做相关运算,运算结果保存在temp中。
4返回结果。
总结下上述过程的重点:1,运算符压栈过程中,当出现两个相邻的‘+’‘-’‘’‘/’运算符时,只要不是前一个是‘+’或‘-’后一个是‘’或‘/’这种情况,那么都可以对前一个运算符先做运算。这样就保证了oper栈中连续的运算符不会超过两个。需要注意的是栈顶是‘*’或‘/’,栈顶的下一个‘+’或‘-’,然后又碰到一个‘+’或‘-’,这种情况需要做两次运算,两次删除栈中的运算符,然后把遇到的运算符压栈。2,temp的使用,计算结果都保存在temp中,temp需要压栈的情况上面都有写出。
class Solution {
public:
int calculate(string s) {
stack<int> num;
stack<char> oper;
int temp=0;
string expression="";
for(int i=0;i<s.size();i++)
{if(s[i]!=' ')
expression+=s[i];
}
for(int i=0;i<expression.length();i++)
{
if(expression[i]-'0'<10&&expression[i]-'0'>-1)
temp=temp*10+expression[i]-'0';
else if(expression[i]=='(')
oper.push(expression[i]);
else
{
if(expression[i]=='*'||expression[i]=='/')
{
if(!oper.empty()&&(oper.top()=='*'||oper.top()=='/'))
{
switch(oper.top())
{
case '*':temp=num.top()*temp;num.pop();oper.pop();break;
case '/':temp=num.top()/temp;num.pop();oper.pop();break;
default: break;
}
}
num.push(temp);
temp=0;
oper.push(expression[i]);
}
else if(expression[i]=='+'||expression[i]=='-')
{
while(!oper.empty()&&(oper.top()=='+'||oper.top()=='-'||oper.top()=='*'||oper.top()=='/'))
{
switch(oper.top())
{
case '*':temp=num.top()*temp;num.pop();oper.pop();break;
case '/':temp=num.top()/temp;num.pop();oper.pop();break;
case '+':temp=temp+num.top();num.pop();oper.pop();break;
case '-':temp=num.top()-temp;num.pop();oper.pop();break;
default: break;
}
}
num.push(temp);
temp=0;
oper.push(expression[i]);
}
else if(expression[i]==')')
{
while(oper.top()!='(')
{
switch(oper.top())
{
case '+':temp=temp+num.top();num.pop();break;
case '-':temp=num.top()-temp;num.pop();break;
case '*':temp=num.top()*temp;num.pop();break;
case '/':temp=num.top()/temp;num.pop();break;
default: break;
}
oper.pop();
}
oper.pop();
}
}
}
while(!oper.empty())
{
switch(oper.top())
{
case '+':temp=temp+num.top();num.pop();break;
case '-':temp=num.top()-temp;num.pop();break;
case '*':temp=num.top()*temp;num.pop();break;
case '/':temp=num.top()/temp;num.pop();break;
default: break;
}
oper.pop();
}
return temp;
}
};