用中缀表达式直接求值,要关注两个点,一个是')',还有一个是数字和符号交替出现,这个交替出现可以用一个布尔变量来表示,我们可以思考发现数字后面要么是符号要么是')',遇到反括号时应该计算出里面的值,还要记得弹出两个括号,而且可以确定的是反括号后面一定是符号(')'或加减乘除)。说的有点乱看代码解释
#include <algorithm>
#include <stack>
using namespace std;
bool priority(const char &a,const char &b){
if(a=='(') return false;//这里要a>b,才会是true,才会弹出栈进行计算,false
//都会压进符号栈可以看到像这种'()'也会把反括号压进符号栈。
if(((a=='+')||(a=='-'))&&((b=='*')||(b=='/')))
return false;
return true;
}
void compute(stack<int> &si,stack<char> &sc){
int a = si.top();
si.pop();
int b = si.top();
si.pop();
char op = sc.top();
sc.pop();
switch(op){
case '+':a=b+a;break;
case '-':a=b-a;break;
case '*':a=b*a;break;
case '/':a=b/a;break;
}
si.push(a);//计算结果压入数字栈
}
int main() {
string str;
while(getline(cin,str)){
stack<int> si;
stack<char> sc;
str = "("+str+")";//先给表达式加个括号,因为下面要和第一个进行比较才进行
//计算
int n =str.size();
bool punct =false;
for(int i =0;i<n;i++){
if(str[i]=='('){
sc.push(str[i]);//遇到括号压进去
}
/*else if(str[i]==')'){
while(priority(sc.top(),str[i])){
compute(si,sc);
}
sc.pop();
}这里最开始没把它统一到下面那个判断条件*/
else if(punct){
while(priority(sc.top(),str[i])){//如果没有加开头的'('那么现在
//符号栈是空的,这里会运行错误。这里是大于才是真,才会运算。
compute(si,sc);
}
sc.push(str[i]);
punct = false;
if(str[i]==')'){如果遇到压的符号是')'应该弹出两个符号,且下一个还
//是符号
sc.pop();
sc.pop();
punct = true;
}
}
else{
int j = i;
if(str[j]=='+'||str[j]=='-') j++;
while(isdigit(str[j])){
j++;
}
string temp = str.substr(i,j-i);
si.push(stoi(temp));
i=j-1;//注意外层i还会+1,所以这里-1
punct = true;//数字完了肯定是符号
}
}//for
cout<<si.top()<<endl;//最后的数字栈剩个结果,符号栈都为空。
}
}
其实还可以将中缀表达式转化为后缀表达式,这样就完全不用考虑括号的问题了,更模块化一点