逆波兰表达式是一种表示运算式的方法,又可以称作后缀表达式,与之相对的是中缀表达式。例如:中缀表达式:a+b*c,后缀表达式:abc*+。这里的例子简单,但是基本表达了两种方法的不同。
下面给出包含“+-*/”以及“()”五种运算符的中缀表达式转后缀表达式的算法流程:
1. 优先级的规定:"()">"*/">"+-",其中"*"=="/","+"=="-"。
2. 输入一组表达式F(包含操作数和上面提到的操作符),准备一个空栈stack
3. 从左往右遍历该表达式中的元素s
4. 如果s是操作数,就直接放置到输出栏output中,否则进行下面的步骤5
5. 如果s是左括号,直接压入stack;
如果s是“+-*/”中任意一个,则分情况操作:
1)stack为空,直接压入stack;
2)当前栈顶元素优先级低于要压入的s,s直接压入stack;
3)当前栈顶元素优先级不低于要压入的s,则将栈顶元素弹出放置到输出栏output,直到stack为空,或者满足2),或者栈顶为左括号就停止,并且将s压入stack;
4)如果s是右括号,则从stack弹出元素,直到弹出一个左括号为止。将刚才弹出的内容(不包括左括号)按弹出顺序放置到输出栏output中。注意:s(右括号)不压入栈。
6.遍历完F表达式,则将stack内容全部弹出到输出栏output中。
按照上面六步就可完成中缀表达式转后缀表达式,现在给个具体的例子:
F=a+b*c+(d*e+f)*g stack=空 output=空
1. s=a,放置到output=a
2. s=+,且stack=空,压入stack=+
3. s=b,放置到output=ab
4. s=*,且“*”>“+”,压入stack=+*
5. s=c,放置到output=abc
6. s=+,且“+”<“*”,弹出*,放置到output=abc*;“+”=“+”,弹出+,放置到output=abc*+;stack=空,压入stack=+。
7. s=(,压入stack=+(
8. s=d,放置到output=abc*+d
9. s=*, 栈顶是(,压入stack=+(*
10. s=e, 放置到output=abc*+de
11. s=+, "+"<"*",弹出*,放置到output=abc*+de*;栈顶是(,压入stack=+(+
12. s=f, 放置到output=abc*+de*f
13.s=),弹出stack,放置到output=abc*+de*f+, 此时stack=+
14.s=*, 压入stack=+*
15.s=g,放置到output=abc*+de*f+g
16.弹出所有stack到output=abc*+de*+g*+
按照上面的顺序得到后缀表达式,那么根据后缀表达式进行计算也比较简单:
从左往右遍历后缀表达式output,遇到操作数压入栈,遇到操作符从栈中弹出两个操作数(加减乘除的操作数都是两个),进行相应的计算,且将计算结果再次压入栈中。如此往复,直到遍历完整个后缀表达式,此时栈内只有一个元素,也就是计算式的结果。