逆波兰表示法

逆波兰表示法(Reverse Polish notation)是一种将操作符放置在操作数后面的表示法。比如3×4用逆波兰式来表示的话,就应当写成3 4 ×。

 

1920年,波兰数学家Jan Łukasiewicz发明了一种数学表示法。它将运算符置于所有的操作数之前。这种表示法也被称为前缀表示法。1954年,弗里德里希·鲍尔和艾兹格·迪科斯彻提出了逆波兰结构来用于表达式求值,以利用堆栈和减少计算机内存访问。之后,澳大利亚哲学家、计算机学家查尔斯·汉布林又对逆波兰记法和相应算法进行了扩充。于是形成了现代的逆波兰表示法,又称后缀表示法。

 

逆波兰式的最大特点在于它的简洁。在一个逆波兰式中,左边运算符的优先级最高,右边运算符的优先级最低。所以,只要从左向右扫描一个逆波兰式,并顺序执行每一个运算符的计算,就可以得到整个表达式的结果。这种计算方式可以很方便的利用堆栈来实现,因此很适合计算机来进行运算。可以说,逆波兰式天生就是为计算机而生的。

 

逆波兰式的解释

逆波兰记法中,操作符置于操作数的后面。例如表达“三加四”时,写作“3 4 +”,而不是“3 + 4”。如果有多个操作符,操作符置于第二个操作数的后面,所以常规中缀记法的“3- 4 + 5”在逆波兰记法中写作“3 4- 5 +”:先3减去4,再加上5。使用逆波兰记法的一个好处是不需要使用括号。例如中缀记法中“3 - 4 * 5”与“(3 - 4)*5”不相同,但后缀记法中前者写做“3 4 5 * -”,无歧义地表示“3 (4 5 *) −”;后者写做“3 4 - 5 *”。

 

逆波兰表达式的解释器一般是基于堆栈的。解释过程一般是:操作数入栈;遇到操作符时,操作数出栈,求值,将结果入栈;当一遍后,栈顶就是表达式的值。因此逆波兰表达式的求值使用堆栈结构很容易实现,和能很快求值。

 

注意:逆波兰记法并不是简单的波兰表达式的反转。因为对于不满足交换律的操作符,它的操作数写法仍然是常规顺序,如,波兰记法“/ 6 3”的逆波兰记法是“6 3 /”而不是“3 6 /”;数字的数位写法也是常规顺序。

 

逆波兰式的实现

在逆波兰式的实现中,最大的问题是如何改变运算符的先后顺序,把高优先级的运算符放在低优先级运算符的左侧。比如,有一个中缀表达式2 + 3 × 4,它所对应的逆波兰式应当是2 3 4 × +。在我们做中缀表达式到逆波兰式转换的时候,必须在不改变操作数顺序的情况下,把高优先级的乘法操作符移动到低优先级的加法运算符的左侧。

 

很自然的,我们会想到堆栈。堆栈具有后进先出的特点。所以我们可以设计一个符号栈,用于临时存储一个中缀表达式中的全部运算符;设计一个RPN数组,用于存储逆波兰式输出。然后从左向右扫描一个中缀表达式,并循环执行以下步骤:

1. 如果扫描到一个运算数,则将其放到RPN数组的末尾

2. 如果扫描到一个运算符。首先比较该运算符和符号栈栈顶运算符的优先级。如果符号栈栈顶运算符的优先级比较低,则将新运算符压入符号栈(这样最后将符号出栈时,高优先级符号先出栈)。如果栈顶符号的优先级更高,就把栈顶符号弹出,并放入RPN数组末尾。然后继续比较新扫描到的运算符和栈顶运算符的优先级,直到找到一个优先级比自己低的栈顶元素或者到达堆栈栈底。

3. 如果表达式扫描结束。将栈中操作符顺序弹出放到RPN数组中。这样就得到了一个逆波兰表达式。

 

如下是一个逆波兰式生成过程的实例。其中绿色部分代表每一步中发生变化的部分。其中特殊之处在于对括弧的处理,括弧的优先级高于所有操作符,但是括弧中所有的操作符优先级又高于括弧。所以当栈顶为括弧的时候,不会将括弧弹出,而是继续压栈。当弹出括弧的时候,也不会把括弧放入逆波兰式中。

 

原中缀表达式:3 + 4 × (5 - 2)/ 2

逆波兰表达式:3 4 5 2 - × 2 / +

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值