中缀表达式转后缀表达式

中缀表达式是最常用的算术表达式,运算符在运算数中间,运算需要考虑运算符优先级.


后缀表达式是计算机容易运算的表达式,运算符在运算数后面,从左到右进行运算,无需考虑优先级,运算呈线性结构.

转换规则

中缀表达式a + b*c + (d * e + f) * g,其转换成后缀表达式则为a b c * + d e * f  + g * +。

转换过程需要用到栈,具体过程如下:

1.从左到右进行遍历
2.运算数(操作数), 直接输出.
3.左括号,直接压入堆栈 , (括号是最高优先级,无需比较) (入栈后优先级降到最低,确保其他符号正常入栈)
4.右括号,(意味着括号已结束) 不断弹出栈顶运算符并输出直到遇到左括号 (弹出但不输出)


5.运算符(操作符),将该运算符与栈顶运算符进行比较,

如果优先级高于栈顶运算符则压入堆栈,
如果优先级低于等于栈顶运算符,则将栈顶运算符弹出并输出,然后比较新的栈顶运算符.
(低于弹出意味着前面部分可以运算,先输出的一定是高优先级运算符,等于弹出是因为同等优先级,从左到右运算)
直到优先级大于栈顶运算符或者栈空,再将该运算符入栈.


6.如果对象处理完毕,则按顺序弹出并输出栈中所有运算符.

 

实例

规则很多,还是用实例比较容易说清楚整个过程。以上面的转换为例,输入为a + b * c + (d * e + f)*g,处理过程如下:

1)首先读到a,直接输出。

2)读到“+”,将其放入到栈中。

3)读到b,直接输出。

此时栈和输出的情况如下:

中缀表达式转后缀表达式

 

4)读到“*”,因为栈顶元素"+"优先级比" * " 低,所以将" * "直接压入栈中。

5)读到c,直接输出。

此时栈和输出情况如下:

中缀表达式转后缀表达式

 

6)读到" + ",因为栈顶元素" * "的优先级比它高,所以弹出" * "并输出, 同理,栈中下一个元素" + "优先级与读到的操作符" + "一样,所以也要弹出并输出。然后再将读到的" + "压入栈中。

此时栈和输出情况如下:

中缀表达式转后缀表达式

 

7)下一个读到的为"(",它优先级最高,所以直接放入到栈中。

8)读到d,将其直接输出。

此时栈和输出情况如下:

中缀表达式转后缀表达式

 

9)读到" * ",由于只有遇到" ) "的时候左括号"("才会弹出,所以" * "直接压入栈中。

10)读到e,直接输出。

此时栈和输出情况如下:

中缀表达式转后缀表达式

 

11)读到" + ",弹出" * "并输出,然后将"+"压入栈中。

12)读到f,直接输出。

此时栈和输出情况:

 中缀表达式转后缀表达式

 

13)接下来读到“)”,则直接将栈中元素弹出并输出直到遇到"("为止。这里右括号前只有一个操作符"+"被弹出并输出。

中缀表达式转后缀表达式

 

14)读到" * ",压入栈中。读到g,直接输出。

中缀表达式转后缀表达式

 

15)此时输入数据已经读到末尾,栈中还有两个操作符“*”和" + ",直接弹出并输出。

中缀表达式转后缀表达式

至此整个转换过程完成。程序实现代码后续再补充了。

括号的运算
中缀表达式转后缀表达式
选取慕课里何钦铭老师的案例
中缀表达式转后缀表达式
 

转换的另一种方法

1)先按照运算符的优先级对中缀表达式加括号,变成( ( a+(b*c) ) + ( ((d*e)+f) *g ) )

2)将运算符移到括号的后面,变成((a(bc)*)+(((de)*f)+g)*)+

3)去掉括号,得到abc*+de*f+g*+