class Solution {
public:
int calculate(string s)
{
stack<int> figure; //用于存储数字
stack<char> ope; //用于存储运算符和括号
string temp = ""; //用于表示当前的数字
for(int i = 0;i < s.size();i++) //遍历s
{
if(s[i] == '+' ||s[i] == '-') //当遇到+运算符的时候,将运算符压入ope中,并且将当前的数字压入figure中
{
if(temp != "")
{
figure.push(atoi(temp.c_str()));
temp = "";
}
if(figure.empty())
{
figure.push(0);
}
if(!ope.empty())
{
if(ope.top() == '-')
{
int a = figure.top();
figure.pop();
int b = figure.top();
figure.pop();
figure.push(b - a);
ope.pop();
}
}
ope.push(s[i]);
}
else if(s[i] == '(')
{
ope.push(s[i]);
}
else if(s[i] == ' ') //遇到空格的时候跳过
{
}
else if(s[i] == ')') //遇到)时,要进行运算
{
if(temp != "")
{
figure.push(atoi(temp.c_str()));
temp = "";
}
while(ope.top() != '(')
{
int a = figure.top();
figure.pop();
int b = figure.top();
figure.pop();
if(ope.top() == '+') //进行运算,并且将运算符出栈。
{
figure.push(b + a);
ope.pop();
}
else
{
figure.push(b - a);
ope.pop();
}
}
ope.pop(); //将(出栈
continue;
}
else
{
temp += s[i];
}
if(i == s.size() - 1)
{
if(temp != "")
{
figure.push(atoi(temp.c_str()));
}
}
}
while(!ope.empty())
{
int a = figure.top();
figure.pop();
int b = figure.top();
figure.pop();
if(ope.top() == '+') //运算
{
figure.push(b + a);
ope.pop();
}
else
{
figure.push(b - a);
ope.pop();
}
}
return figure.top();
}
};
算法思路:
用一个figure栈来存储数字,一个ope栈来存储操作符和括号。
因为+号可以不用考虑运算的顺序,所以对加号不需要特殊处理
但是-号如 2-3-1,是需要先运算前面的负号的,所以对于负号需要进行特殊的考虑
首先如果figure栈为空,说明为 -1等这种类型开头,需要先压入0进行运算,而且int类型负数范围是比正数范围大的,所以不用担心溢出的问题
如果当前检测到为运算符的时候,若ope栈栈顶元素为-,则需要先进行减法处理,处理完了之后再将当前的运算符压入栈中。
对于括号的处理,如果是(,则直接压入ope栈中,然后如果检测到)的时候,需要将ope栈内的操作符出栈运算一部分,直到栈顶元素为(为止。
当遍历到s的最后一个元素的时候,如果temp不为空,需要将temp转换为int类型压入到栈中。
最后若运算符不为空,再对两个栈进行运算处理。