前缀表达式
前缀表达式又称波兰式,前缀表达式的运算符位于操作符之前。
例:(3+4)5-6对应的前缀表达式就是 - * + 3 4 5 6
如何将中缀表达式(3+4)5-6转换成前缀表达式 - * + 3 4 5 6。
将中缀表达式转换为前缀表达式:
遵循以下步骤:
- 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
从右至左扫描中缀表达式;
遇到操作数时,将其压入S2;
遇到运算符时,比较其与S1栈顶运算符的优先级:
如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;
若优先级比栈顶运算符的较高或相等,也将运算符压入S1;
否则,将S1栈顶的运算符弹出并压入到S2中,再次转到与S1中新的栈顶运算符相比较;
遇到括号时:
如果是右括号“)”,则直接压入S1;
如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;
重复步骤(2)至(5),直到表达式的最左边;
将S1中剩余的运算符依次弹出并压入S2;
依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。
因此中缀表达式(3+4)*5-6转换成前缀表达式 的结果是 - * + 3 4 5 6。
前缀表达式求值
- 从右至左扫描表达式,遇到数字时将数字压入栈,遇到运算符,弹出栈顶的2个数,用运算符做出计算,并把计算的结果入栈;重复上述过程,直到表达式的左端,最后运算得出的值即为表达式的结果。
后缀表达式
- 将中缀表达式转换为后缀表达式
初始化两个栈:运算符栈S1和储存中间结果的栈S2;
从左至右扫描中缀表达式;
遇到操作数时,将其压入S2;
遇到运算符时,比较其与S1栈顶运算符的优先级:
如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);
否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
遇到括号时:
如果是左括号“(”,则直接压入S1;
如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;
重复步骤(2)至(5),直到表达式的最右边;
将S1中剩余的运算符依次弹出并压入S2;
依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。
例如,将中缀表达式“1+((2+3)×4)-5”转换为后缀表达式的结果就是:1 2 3 + 4 × + 5 -
后缀表达式的计算机求值:
- 与前缀表达式类似,只是顺序是从左至右:
从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素 op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。
例如后缀表达式“3 4 + 5 × 6 -”:
(1) 从左至右扫描,将3和4压入堆栈;
(2) 遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素,注意与前缀表达式做比较),计算出3+4的值,得7,再将7入栈;
(3) 将5入栈;
(4) 接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈;
(5) 将6入栈;
(6) 最后是-运算符,计算出35-6的值,即29,由此得出最终结果。
代码
#include<bits/stdc++.h>
#include<stack>
using namespace std;
int top=0,i;
char b;
int main()
{
stack<char >s,ss;
char a[10000];
cin>>a;
int len=strlen(a);
for(int i=len-2;i>=0;i--)
{
if(a[i]<='z'&&a[i]>='a')
s.push(a[i]);
if(a[i]==')')
{
ss.push(a[i]);
}
if(a[i]=='(')
{
while(ss.top()!=')')
{
b=ss.top();
s.push(b);
ss.pop();
}
ss.pop();
}
if(a[i]=='+'||a[i]=='-')
{
while(!ss.empty()&&(ss.top()=='*'||ss.top()=='/')){
b=ss.top();
ss.pop();
s.push(b);
}
ss.push(a[i]);
}
if(a[i]=='*'||a[i]=='/')
{
ss.push(a[i]);
}
}
while(!ss.empty()){
b=ss.top();
ss.pop();
s.push(b);
}
while(!s.empty())
{
cout<<s.top();
s.pop();
}
cout<<endl;//前缀表达式
for(int i=0;i<len-1;i++)
if(a[i]=='('||a[i]==')') continue;
else cout<<a[i];
cout<<endl;//中缀表达式
for(int i=0;i<len-1;i++){
if(a[i]>='a'&&a[i]<='z') cout<<a[i];
else{
if(a[i]=='+'||a[i]=='-'){
if(s.empty()||s.top()=='(') s.push(a[i]);
else{
while(!s.empty()&&s.top()!='('){
cout<<s.top();
s.pop();
}
s.push(a[i]);
}
}
if(a[i]=='*'||a[i]=='/'){
if(s.empty()||s.top()=='('||s.top()=='+'||s.top()=='-') s.push(a[i]);
else{
while(!s.empty()&&s.top()!='('){
cout<<s.top();
s.pop();
}
s.push(a[i]);
}
}
if(a[i]=='(') s.push(a[i]);
if(a[i]==')'){
while(s.top()!='('){
cout<<s.top();
s.pop();
}
s.pop();
}
}
}
while(!s.empty()){
cout<<s.top();
s.pop();
}//后缀表达式
return 0;
}