概念:
后缀表达式是相较于中缀表达式而言的,像我们平时写的2+3*(4-(5+6))/7就是一个中缀表达式,那么如何将之变为后缀表达式呢?后缀表达式如何用来求解呢?
先来第一个问题(中缀->后缀):
变为后缀表达式方法(规则):
1.遇到操作数:直接添加到后缀表达式中
2.栈为空时,遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈。
6.最终将栈中的元素依次出栈,输出。
用一个实例来分析:
X = 2+3*(4-(5+6))/7
1、遇到操作数2,添加到后缀表达式中 2 (此时的后缀表达式,下同)
2、栈为空,遇到加号‘+’,将‘+’入栈 2
3、遇到操作数3,添加到后缀表达式中 23
4、遇到操作符‘*’,栈顶为‘+’,‘*’优先级大于‘-’,不出栈,‘*’入栈 23
5、遇到左括号‘(’,直接入栈。 23
6、遇到操作数4,添加到后缀表达式中 234
7、遇到减号‘-’,栈顶为‘(’,‘-’入栈 234
8、遇到左括号‘(’,直接入栈。 234
9、遇到操作数5,添加到后缀表达式中 2345
10、遇到加号‘+’,栈顶为‘(’, ‘+’入栈 2345
11、遇到操作数6,添加到后缀表达式中 23456
12、遇到右括号‘)’(不入栈),出栈‘+’,出栈‘(’(不添加到后缀表达式中) 23456+
13、遇到右括号‘)’(不入栈),出栈‘-’,出栈‘(’(不添加到后缀表达式中) 23456+-
14、遇到‘/’,栈顶为‘*’, ‘/’优先级大于‘*’,将‘*’出栈 23456+-*
15、遇到操作时7,添加到后缀表达式中 23456+-*7
16、把栈中剩下的符号都出栈 23456+-*7/+
代码实现:
char* postfix_expression(string str)
{
char *temp=new char(100);
int j=0;
for(int i=0; i<str.size(); i++)
{
if(str[i]>='0' && str[i]<='9')
temp[j++]=str[i];
else
{
if(str[i]==')')
{
while(S_c.top()!='(')
{
temp[j++] = S_c.top();
S_c.pop();
}
S_c.pop();
}
//如果符号是*或/高优先级,弹出所有*和/
else if(str[i]=='*'||str[i]=='/')
{
if(!S_c.empty())
if(S_c.top()=='*'||S_c.top()=='/')
{
temp[j++] = S_c.top();
S_c.pop();
}
S_c.push(str[i]);
}
//如果符号是+或-低优先级,弹出所有*/+-
else if(str[i]=='+'||str[i]=='-')
{
if(!S_c.empty())
if(S_c.top()=='*'||S_c.top()=='/'||S_c.top()=='+'||S_c.top()=='-')
{
temp[j++] = S_c.top();
S_c.pop();
}
S_c.push(str[i]);
}
else
S_c.push(str[i]);
}
}
while(!S_c.empty())
{
temp[j++] = S_c.top();
S_c.pop();
}
return temp;
}
第二个问题,如何使用后缀表达式来解表达式
后缀表达式已经将计算的优先顺序排好,只需要将后缀表达式的数字逐个入栈,直到遇到符号,将前栈顶两个元素运算放回栈顶即可。
以上面的后缀表达式为例:
23456+-*7/+
上代码~
#include <iostream>
#include <string>
#include <cstring>
#include <stack>
using namespace std;
stack<int> S_n;
stack<char> S_c;
//上面的后缀表达式转换函数
char* postfix_expression(string str);
int main()
{
string str;
char *pe;
int temp;
cin>>str;
//将str转为后缀表达式
pe = postfix_expression(str);
for(int i=0; i<strlen(pe); i++)
{
if(pe[i]>='0'&&pe[i]<='9')
{
S_n.push(pe[i]-'0');
}
else if(pe[i]=='*')
{
temp = S_n.top();
S_n.pop();
temp *= S_n.top();
S_n.pop();
S_n.push(temp);
}
else if(pe[i]=='/')
{
temp = S_n.top();
S_n.pop();
temp = S_n.top()/temp;
S_n.pop();
S_n.push(temp);
}
else if(pe[i]=='+')
{
temp = S_n.top();
S_n.pop();
temp += S_n.top();
S_n.pop();
S_n.push(temp);
}
else if(pe[i]=='-')
{
temp = S_n.top();
S_n.pop();
temp = S_n.top()-temp;
S_n.pop();
S_n.push(temp);
}
}
cout<<pe<<endl;
cout<<S_n.top()<<endl;
return 0;
}
运行结果:
来源:oschina
链接:https://my.oschina.net/u/4366189/blog/4394426