正常表达式是中缀表达式,转化成后缀表达式之后方便计算值。
需要注意的几点是。
1.栈空直接将运算符号入栈。
2.有元素,且栈顶元素优先级小于现有元素优先级,则放入,因为后边可能比改元素优先级还要高。
3.栈顶元素优先级大于或等于当前元素,那么,必然是前面的先算,因此可以循环控制,将前面的优先级大于或等于当前元素优先级的符号都输出。
4.控制左括号时,左括号进栈优先级降为最低。右括号进栈时,直接输出内部符号,直到碰到对应的左括号。
#include<bits/stdc++.h>
using namespace std;
struct Operator
{
char op;
int level;
};
stack<Operator>stk;
string s;
int main()
{
while(cin>>s)
{
int pos=0;
while(pos<s.size())
{
if(s[pos]>='0'&&s[pos]<='9') //如果是数字,那么把数字读全,然后输出这个数字
{
int temp=0;
while(pos<s.size()&&(s[pos]>='0'&&s[pos]<='9'))
{
temp*=10;
temp+=s[pos]-'0';
pos++;
}
cout<<temp<<" ";
}
else//如果是字符
{
Operator thisop;
thisop.op=s[pos];
if(s[pos]=='+'||s[pos]=='-')
thisop.level=1;
else if(s[pos]=='*'||s[pos]=='/')
thisop.level=2;
else if(s[pos]=='^')
thisop.level=3;
else if(s[pos]=='('||s[pos]==')')
thisop.level=4;
//根据操作符定义他们的等级
if(stk.empty()){//如果栈空,直接进入,特判(
if(thisop.op=='(')
thisop.level=0;
stk.push(thisop);
}
else//非空则需要判断栈顶元素和当前元素的优先级
{
Operator temp;
temp=stk.top();//获取栈顶的操作符号优先级
if(temp.level<thisop.level) //如果自身优先级比先前的大,那么继续先存着,因为不知道后边有没有比自身还要大的
{
if(thisop.op=='(')//左括号入队之后优先级降低成最低
thisop.level=0;
else if(thisop.op==')')//右括号不入栈,直接把从右括号到左括号中间的元素全部操作完
{
while(stk.top().op!='(')
{
cout<<stk.top().op<<" ";
stk.pop();
}
stk.pop();
}
if(thisop.op!=')')
stk.push(thisop);
}
else //现在的操作符小于先前的,那么必然是先前的先输出
{
while(!stk.empty()&&stk.top().level>=thisop.level){
cout<<stk.top().op<<" ";
stk.pop();
}
stk.push(thisop);
}
}
pos++;
}
}
while(!stk.empty()){
cout<<stk.top().op<<" ";
stk.pop();
}
cout<<endl;
}
return 0;
}