逆波兰表达式(后缀表达式)2

逆波兰表达式
逆波兰表达式又叫做后缀表达式。在通常的表达式中,运算符总是置于与之相关的两个运算对象之间,所以,这种表示法也称为中缀表示。波兰逻辑学家 J.Lukasiewicz于1929年提出了另一种表示表达式的方法。按此方法,每一运算符都置于其运算对象之后,故称为后缀表示。

逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子:
正常的表达式      逆波兰表达式  
a+b   --->  a,b,+   
a+(b-c) --->  a,b,c,-,+   
a+(b-c)*d   --->  a,b,c,-,d,*,+   
a+d*(b-c)     --->  a,d,b,c,-,*,+

逆波兰表达式的用途
它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。其运算方式如下: 按顺序扫描逆波兰表达式,如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元
素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。

中序表达式转换为逆波兰表达式
1、建立运算符栈stackOperator用于运算符的存储,此运算符在栈内遵循越往栈顶优先级越高的原则
2、预处理表达式,正、负号前加0(如果一个加号(减号)出现在最前面左括号后面,则该加号(减号) 为正负号) 。   
3、顺序扫描表达式,如果当前字符是数字(优先级为0的符号),则直接输出该数字;如果当前字符为运算符或括号(优先级不为0的符号),则判断第4点 。   
4、若当前运算符为'(',直接入栈;
若为')',出栈并顺序输出运算符直到遇到第一个'(',遇到的第一个'('出栈但不输出;
若为其它,比较stackOperator栈顶元素与当前元素的优先级:如果栈顶元素是'(',当前元素入栈;如果栈顶元素 >= 当前元素,出栈并顺序输出运算符直到 栈顶元素 < 当前元素,然后当前元素入栈;   如果 栈顶元素 < 当前元素,直接入栈。
5、重复第3点直到表达式扫描完毕。  
6、顺序出栈并输出运算符直到栈元素为空。

上面的算法比较抽象,下面来个实际例子

写一个方法,参数传递一个字符串表达式,返回结果为表达式计算结果。
如:传递表达式"5 + ((1 + 2) * 4) − 3"返回计算的结果。
1.将中缀表达式转换为逆波兰表达式
1)建立一个运算符栈stackOperator用来存放运算符;建立一个字符串链表reversePolishExpression用来存放逆波兰表达式
2)顺序扫描"5 + ((1 + 2) * 4) − 3",根据算法可以得出stackOperator及reversePolishExpression值的变化过程:

扫描     操作    stackOperator值    reversePolishExpression值           注释

5           输出               空                                 5                            当前字符是数字直接输出该数字
+           入栈               +                                  5                             栈顶元素为空,不用比较,入栈
(           入栈                (                                   5                             当前运算符为'(',直接入栈
(           入栈                (  (                                5                             当前运算符为'(',直接入栈
1          输出                (  (                                5 1                          当前字符是数字直接输出该数字
+          入栈                (  ( +                             5  1                         + 优先级< 栈顶元素 ( ,入栈
2          输出                (  ( +                             5  1  2                     当前字符是数字直接输出该数字
)           出栈                (                                   5   1  2  +                出栈并顺序输出运算符直到遇到第一个'('
*           入栈                (  *                                5   1  2  +                 * 优先级< 栈顶元素 ( ,入栈
4          输出                (  *                                5   1  2  +  4             当前运算符为'(',直接入栈
)           输出                空                                 5   1  2  +  4  *          出栈并顺序输出运算符直到遇到第一个'('
-            入栈                -                                   5   1  2  +  4  *          栈顶元素为空,不用比较,入栈
3          输出                 -                                   5   1  2  +  4  *  3      当前字符是数字直接输出该数字
最后     输出                空                                  5   1  2  +  4  *  3  -   顺序出栈并输出运算符直到栈元素为空

下表给出了该逆波兰表达式从左至右求值的过程,堆栈栏给出了中间值,用于跟踪算法。 输入 操作 堆栈 注释 5 入栈 5 1 入栈 5, 1 2 入栈 5, 1, 2 + 加法运算 5, 3 (1, 2)出栈;将结果(3)入栈 4 入栈 5, 3, 4 * 乘法运算 5, 12 (3, 4)出栈;将结果(12)入栈 + 加法运算 17 (5, 12)出栈;将结果 (17)入栈 3 入栈 17, 3 − 减法运算 14 (17, 3)出栈;将结果(14)入栈

计算完成时,栈内只有一个操作数,这就是表达式的结果:14

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值