对前缀表达式转后缀表达式符合以下规则
需要一个辅助的符号栈存储暂时不能确定顺序的运算符
1)后缀与前缀表达式中运算数顺序是不会变的
从左往右读:
2)遇到操作数直接加入后缀表达式
3)遇到界限符'('压入符号栈,当遇到')'时弹出运算符加入后缀表达式直到'('弹出为止`括号是不加入后缀表达式的`
4)遇到运算符,弹出栈中优先级高于或等于的运算符加入后缀表达式,直到栈空或遇到'('停止,`再将此运算符加入符号栈`
5)当运算公式全部读完,再将符号栈中符号依次弹出
中缀表达式求值需要分两步 中缀转后缀,后缀表达式求值
需要用到两个数组栈,一个存放运算符,一个存放转化后的后缀表达式。
对于运算符栈,设栈顶top指针指向栈最顶元素,当读取到上面表达式的其他运算符
时就要与top所指向的运算符比较,不妨设top指向的运算符为a,表达式中读取的运算符为b;
如果a>=b,(这里指优先级)则a弹出top向下移动b再与top比较;直到遇到终止
条件。
而对于a,b运算符的优先级则需要提前设定优先级表;本方法思路是建立优先级二维数组,数组坐标由a,b组成,这样每有一组a,b就对应一个结果,而结果仅有两种要么弹出要么压入
蓝色代表运算符栈内元素a,黄色代表b
>
代表a>b
则a弹出;不妨>
编码为0
;<
编码为1
。再为±*/运算符编码。如图:
如此运算符优先级二维数组就算形成了
#include<iostream>
#include<iostream>
using namespace std;
int pd(char x){ //为运算符编号函数
int p=0;
switch(x)
{case'+':p=0;break;
case'-':p=1;break;
case'*':p=2;break;
case'/':p=3;break;
case'(':p=4;break;
case')':p=5;break;
}
return p;}
int main(){
//运算符优先级二维数组
int sz[5][6]={{0,0,1,1,1,0},{0,0,1,1,1,0},{0,0,0,0,1,0},{0,0,0,0,1,0},{1,1,1,1,1,0}};
string s; //设表达式为s
cout<<"输入表达式"<<endl;
cin>>s;
char ysf[20]; //运算符栈
int top=0; //记录栈最顶端
char hz[20]; //后缀表达式
int next=0; //记录后缀最顶元素
ysf[0]='#';
hz[0]='#';
int f=0; //用于接受数组判断的值1或0
for(int i=0;s[i]!='\0';i++){
if(s[i]=='('||s[i]==')'||s[i]=='*'||s[i]=='/'||s[i]=='+'||s[i]=='-')
{ if(ysf[top]=='#')
ysf[++top]=s[i];
else
{int b=pd(s[i]); //读取b并编码
while(f!=1&&top>=0){
int a=pd(ysf[top]); //读取a并编码
if(top==0)break; //为b=")"时的终止条件
if(b==5&&a==4) //为b=")"时的终止条件
{f=1;top--;break;}
f=sz[a][b]; //判断两个符号对应的><
if(f==0) //当数组对应元素为0,a出运算符栈
{hz[++next]=ysf[top];
top--;}
}
f=0;
//对b操作
if(s[i]!=')')
ysf[++top]=s[i];//所有a>b之出栈之后b运算符入栈
}
}
else hz[++next]=s[i]; //如果读到非运算符直接进入后缀表达式
}
if(top!=0) //当s被读完时,判断运算符栈中是否含有未输出的运算符
for(int i=0;i<=top;i++)
hz[++next]=ysf[top--];
for(int i=1;i<=next;i++)//输出后缀表达式
cout<<hz[i];
}
运行结果