后缀表达式学习

昨天笔试,遇到一个后缀表达式,忘记了,用了很多时间回忆,才得以解决,今天决定去查一查。


一、定义
上网查一查:中缀表达式是我们从小就用的一个表达式,从百度百科中拿来了三者的定义(来源于百度百科):
中缀表达式(或中缀记法)是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法。
后缀表达式:不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则,如:(2 + 1) * 3 ,即2 1 + 3 *
前缀表达式:不含括号的算术表达式,而且它是将运算符写在前面,操作数写在后面的表达式,为纪念其发明者波兰数学家Jan Lukasiewicz也称为“波兰式”。例如,- 1 + 2 3,它等价于1-(2+3)。
对于中缀表达式,它有很多括号,而前后缀则没有,如果叫计算机去计算中缀表达式,这是很困难的事情,这样不只遍历一次了。


二、三者与二叉树关系
这三个表达式与二叉树的遍历很有联系:
前缀表达式<------>前序遍历;
中缀表达式<------>中序遍历;
后缀表达式<------>后序遍历;
其实有时候,我们可以用二叉树作为中间的工具,对于平时看到中序表达式,根据它的运算法则去构那一棵二叉树。
根据中缀表达式生成二叉树(by donhao 引用【2】)
中缀表达式:a + b * (c - d) - e / f
中序遍历为:左儿子、右儿子、根节点
按照操作符的优先级,其二叉树生成过程为:
1. c-d的优先级高,根是-操作符,c和d分别为左右儿子
       -
     |    |
     c  d
2.接下来是乘法,根是*操作符,b和1中的内容分别是左右儿子
       *
   |       |
  b        -
          |  |
         c d
3.接下来是触发,根是/操作符,e和f分别是左右儿子
            /
          |  |
         e f
4.接下来是加法,根是+操作符,a和2中的内容分别是左右儿子
      +  
 |        |
a         *
       |       |
       b        -
                |  |
               c d
还包括3中的那棵树。
5.  接下来是减法,根是-操作符,4中的两棵树分别是左右儿子
                 -
    |                           |
   +                           /
 |     |                     |    |
a         *                e    f
       |        |
       b        -
                |  |
               c d   
根据二叉树前序遍历得到前缀表达式
前序遍历为:根节点、左儿子、右儿子
得到前缀表达式为:- + a * b - cd / ef
根据二叉树后序遍历得到后缀表达式
后序遍历为:左儿子、右儿子、根节点
得到后缀表达式为:abcd - * + ef / -

 

三、如何计算后缀表达式
输入:后缀表达式P
处理:栈S,功能用来存入操作数与计算的中间量,类型是数值就得了。从左向右逐个逐个字符扫描P的字符串,如果遇到操数放入S中;遇到运算符,就从S中取出栈顶的两个操作数计算,计算的结果再压入栈中。重复这样的工作,到最后S中只有一个值了,这个值就是所求。
输出:S中最后一个值

 

四、中缀表达式到后缀表达式转换(引用【1】)
如下图的模型:


Graphical illustration of algorithm, using a three way railroad junction. The input is processed one symbol at a time, if a variable or number is found it is copied direct to the output b), d), f), h). If the symbol is an operator it is pushed onto the operator stack c), e), however, if its precedence is less than that of the operator at the top of the stack or the precedences are equal and the operator is left associative then that operator is popped off the stack and added to the output g). Finally remaining operators are popped off the stack and added to the output.
注:
Graphical illustration of algorithm:算法示意图
 precedence:优先级
 associative:结合
operator:运算符

 

中缀到后缀的详细例子:


 

 

五、总结

中缀表达式转换成后缀表达(by xiazdong 引用【3】)
此方法需要遵循几个规则:
(1)如果读入操作数,则直接放入输出字符串;
(2)如果读入一般运算符如+-*/,则放入堆栈,但是放入堆栈之前必须要检查栈顶,并确定栈顶运算符的优先级比放入的运算符的优先级低;如果放入的优先级较低,则需要将栈顶的运算符放入输出字符串;
(3)如果读入(,因为左括号优先级最高,因此放入栈中,但是注意,当左括号放入栈中后,则优先级最低;
(4)如果读入),则将栈中运算符取出放入输出字符串,直到取出(为止,注意:()不输出到输出字符串;
(5)顺序读完表达式,如果栈中还有操作符,则弹出,并放入输出字符串;
  
计算后缀表达
规则如下:
(1)如果是操作数,则放入栈中;
(2)如果是操作符,则取出栈中两个操作数,进行运算后,将结果放入栈中;
(3)直到最后栈中只有一个元素,此元素就是计算结果;

 

引用:
【1】http://en.wikipedia.org/wiki/Shunting-yard_algorithm
【2】http://blog.csdn.net/donhao/article/details/5677523
【3】http://blog.csdn.net/xiazdong/article/details/7272693


 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值