中缀表达式转换为后缀表达式的规则:
中缀表达式a + b*c + (d * e + f) * g,转换成后缀表达式为a b c * + d e * f + g * +。中缀表达式转换为后缀表达式的过程需要用到栈,具体过程如下:
1)从左遍历中缀表达式,如果遇到操作数,直接将其输出。
2)如果遇到操作符“+”, “-”,“*”, “/”,
- 如果栈为空,则将其压入到栈中;
- 如果栈不为空,
- 如果栈顶的操作符的优先级较高,或与之相等,则弹出栈顶的操作符并输出,继续比较,直到遇见优先级较低的操作符(或者栈为空)为止,再将刚才遇见的操作符压入栈中。
- 如果栈顶操作符的优先级较低,则直接将遇到的操作符压入栈中。
3)如果遇到括号:
- 如果遇到左括号“(”,直接将其压入栈中;
- 如果遇到右括号“)”,则将栈里的操作符依次弹出并输出,直到遇到左括号为止(注意,左括号弹出并不输出)。
4)如果我们遍历到了中缀表达式的的末尾,而此时栈非空,则将栈中剩余的所有操作符依次弹出并输出。
需要说明的是,“(”")"的优先级最低,其次是“+”“-”,“*”“/”的优先级最高。
实例:
以中缀表达式a + b*c + (d * e + f) * g转换为后缀表达式a b c * + d e * f + g * +为例:
从左向右遍历中缀表达式:
- 遇到a,输出,此时的后缀表达式为 :a;
- 遇到+,此时栈为空,将+直接压入栈中,此时栈中的元素为 :顶 + 底;
- 遇到b,输出,此时的后缀表达式为:a b;
- 遇到*,与栈顶操作符+比较,+的优先级较低,将*压入栈中,此时栈中的元素为:顶 * + 底;
- 遇到c,输出,此时的后缀表达式为:a b c;
- 遇到+,与栈顶操作符*比较,*的优先级较高,弹出*并输出;再与栈顶元素+比较,+的优先级与之相等,弹出+并输出,此时栈为空,将+压入栈中,此时栈中的元素为:顶 + 底,此时的后缀表达式为a b c * +;
- 遇到(,直接压入栈中,此时栈中的元素为 :顶 ( + 底;
- 遇到d,输出,此时的后缀表达式为:a b c * + d;
- 遇到*,与栈顶操作符(比较,(的优先级较低,将*压入栈中,此时栈中的元素为 :顶 * ( + 底;
- 遇到e,输出,此时的后缀表达式为:a b c * + d e;
- 遇到+,与栈顶操作符*比较,*的优先级较高,弹出*并输出;再与栈顶元素(比较,(的优先级较低,将+压入栈中,此时栈中的元素为 :顶 + ( + 底,此时的后缀表达式为:a b c * + d e *;
- 遇到f,输出,此时的后缀表达式为:a b c * + d e * f;
- 遇到),依次弹出栈顶元素并输出,直到遇到左括号(为止,(弹出并不输出,完成操作之后栈中的元素为 :顶 + 底,此时的后缀表达式为:a b c * + d e * f +;
- 遇到*,此时栈为空,将*直接压入栈中,此时栈中的元素为 :顶 * + 底;
- 遇到g,输出,此时的后缀表达式为:a b c * + d e * f g;
- 中缀表达式遍历结束,此时栈中的元素为顶 * + 底,将栈中剩余的所有操作符依次弹出并输出,完成操作之后的后缀表达式为:a b c * + d e * f g * +;
实现代码(C++):
#include <iostream>
#include <cstdio>
#include <string>
#include <stack>
using namespace std;
int Priority(char op) { //判断操作符的优先级
if(op=='('||op==')') return 1;
else if(op=='+'||op=='-') return 2;
else if(op=='*'||op=='/') return 3;
}
string transfer(string str) { //将中缀表达式转换为后缀表达式
string _str="";
stack<char> s;
int i=0;
while(str[i]!='\0') {
if(str[i]-'0'>=0&&str[i]-'0'<=9) //扫描到的是数字
_str+=str[i];
else { //扫描得到的是操作符
if(str[i]!='('&&str[i]!=')') { //操作符非括号
if(s.empty()) //如果栈是空的
s.push(str[i]);
else{ //如果栈不为空
int p=Priority(str[i]);
if(p>Priority(s.top())) //如果遇到的操作符的优先级,大于栈顶操作符的优先级
s.push(str[i]);
else { //如果遇到的操作符的优先级,小于或等于栈顶操作符的优先级
char temp;
while((!s.empty())&&(p<=Priority(s.top()))){ //弹出栈顶操作符并输出,直到遇到的操作符的优先级大于栈顶操作符的优先级,或者栈为空
temp=s.top();
_str+=temp;
s.pop();
}
s.push(str[i]);
}
}
}
else { //操作符是括号
if(str[i]=='(') //如果操作符是左括号
s.push(str[i]);
else { //如果操作符是右括号
char temp=s.top();
while(temp!='('){
_str+=temp;
s.pop();
temp=s.top();
}
s.pop();
}
}
}
++i;
}
while(!s.empty()){ //将栈中剩余的操作符依次输出
_str+=s.top();
s.pop();
}
return _str;
}
int main() {
string str="1+2*3+(4*5+6)*7";
cout<<transfer(str)<<endl;
return 1;
}