中缀表达式就是我们正常工作中写的表达式,如 a+(b-c)*d
,编译系统将中缀表达式改写 abc-d*+
,这种运算符在操作数后面称为后缀表达式(也称逆波兰表达式)。
后缀表达式最方便的作用就是在计算的时候直接操作栈出栈就可以了。
转换过程需要用到栈,这里用两个栈,stack 栈用来存放运算符,post 栈用来存放最后的后缀表达式。具体规则如下:
运算符一共三种情况,操作数,符号,括号
开始:
(1)该运算符若是操作数,直接存入 post 栈。
(2)该运算符是左括号 (
, 则直接存入 stack 栈。
(3)该运算符是右括号 )
,则将 stack 栈中 (
右的所有运算符出栈,存入 post 栈。
(4)若该运算符为符号(加减乘除等),则将该符号(称为X)和 stack 栈顶符号作比较:若X优先级高于栈顶符号,则直接存入 stack 栈;若X优先级低于或等于栈顶符号则将栈顶符号出栈存入post,然后继续对比栈顶符号,直到stack栈为空或者遇到比X运算等级低的符号停止。然后将X入stack栈。
(5)当扫描完后,stack 栈中还有运算符时,则将所有运算符出栈,存入 post 栈。
例子:中缀表达式 a + b * c + (d * e + f) * g
,其转换成后缀表达式则为a b c * + d e * f + g * +
。
扫描 | stack 栈(也叫操作符栈) | post 栈(也可认为是直接输出) |
---|---|---|
a | 空 | a |
a+ | + | a |
a+b | + | ab |
a+b* | +* | ab |
a+b*c | +* | abc |
a+b*c+ | + | abc*+ |
a+b*c+( | +( | abc*+ |
a+b*c+(d | +( | abc*+d |
a+b*c+(d* | +(* | abc*+d |
a+b*c+(d*e | +(* | abc*+de |
a+b*c+(d*e+ | +(+ | abc*+de* |
a+b*c+(d*e+f | +(+ | abc*+de*f |
a+b*c+(d*e+f) | + | abc*+de*f+ |
a+b*c+(d*e+f)* | +* | abc*+de*f+ |
a+b*c+(d*e+f)*g | +* | abc*+de*f+g |
a+b*c+(d*e+f)*g# | 空 | abc*+de*f+g*+ |
注意:表格中第6步,读到
+
,因为栈顶符号*
的优先级高,所以*
出栈,栈中下一个元素+
优先级与读到的操作符+
一样,所以也要弹出。然后再将读到的+
压入栈中。
第13步,读到)
,则直接将栈中元素弹出直到遇到(
为止。这里左括号前只有一个操作符+
被弹出。
转自:https://www.jianshu.com/p/fcd2b521a3e2
略为修改 csdn现在投转载太麻烦了,所以投原创了