后缀表达式(逆波兰式)


  昨天晚上在大话数据结构这本书上看到栈的时候,作者用逆波兰式举了个例子,我觉得挺好玩的,做个笔记

  什么是逆波兰式

  
  20世纪50年代,波兰的一位逻辑学家Jan Lukasiewicz,想到了一种不需要括号的后缀表达法,后来我们把其称之为逆波兰(Reverse Polish Notation RPN)表示。这种表达式极大程度上利用了栈先进后出的原则,巧妙的解决了程序实现四则运算的难题。(先乘除,后加减)

  tip:为什么不叫Jan Lukasiewicz表达式,可能名字太复杂了,参考布隆过滤器和霍夫曼树

  举个例子:

  现有算式:9+(3-1)×3+10÷2,这个式子用正常的数学表达式(也叫中缀表达式,运算符号在运算数字中间)就是它本身。

  用后缀表示法就是: 9 3 1 - 3 × + 10 2 / +(运算符号在运算数字后面)

  叫后缀表达式的原因在于所有的符号都是要出现在使用了这个运算符的数字后面,没错是很绕,看着也难受,举个例子,1+2的后缀表达式为1 2 +。

  逆波兰式(后缀表达式)的运算结果


  对于“9+(3-1)×3+10÷2”大家都知道怎么算,按照先乘除后加减的运算法则计算即可,但是计算机如果按照普通的运算法则进行四则运算,效率应该不会很高(我猜的),那用后缀表达式计算机是怎么计算的呢?

  后缀表达式: 9 3 1 - 3 × + 10 2 / +

  规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,讲处于栈顶对的两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。

  (1) 初始化一个空栈,用于数字运算

  (2)后缀表达式 的前三个都是数字,按照规则直接入栈,现在栈中有三个数字(9,3,1)。(从左到右,最左边的数字在栈底)

  (3)接下来是“-”运算符,按照规则将3和1拿出来加上运算符进行计算,3-1=2,得到结果入栈,现在栈中有两个数字(9,2)

  (4)数字3进栈,栈中现有(9,2,3)

  (5)后面是预算符"×",按照规则,取出2和3进行运算,2×3=6,将6入栈,栈中现有(9,6)

  (6)后面是运算符"+",按照规则,取出9和6进行运算,9+6=15,将结果15入栈,栈中现有(15)

  (7)后面是两个数字,10和2,直接入栈,栈中现有(15,10,2)

  (8)接下来是运算符"/",按照规则,取出10和2进行运算,10/2=5,将5入栈,栈中现有(15,5)

  (9)最后一个运算符也是最后一个元素是"+",将栈中仅剩的15和5取出进行运算,15+5=20,20就是该后缀表达式的结果。

  这种方式,既遵循了先乘除后加减的运算法则,并且能提升计算机进行四则运算的效率。

  那么用中缀表达式怎么推导出后缀表达式呢?


  中缀表达式转后缀表达式(逆波兰式)


  中缀表达式“9+(3-1)×3+10÷2”转化为后缀表达式“ 9 3 1 - 3 × + 10 2 / +”

  规则:从左到右遍历表达式每个数字和符号,若是数字就直接输出,成为后缀表达式的一部分;若是符号,先与栈顶的符号做一个优先级的比较,是右括号或优先级不高于栈顶符号(加减乘除,乘除优先),则栈顶元素一次出栈并输出,并将当前元素进栈,一直到后缀表达式输出完毕。

  (1) 初始化一个空栈,用于符号的进出栈

  (2)第一个数字是9直接输出,9后面是原算符"+","+“号进栈,现在输出为"9”,栈中现有("+")。(注意这里是看中缀表达式,也就是正常的数学表达式,不要看看混了

  (3)第三个字符是"(",是运算符,因为括号需要配对,所以直接进栈。栈中现有("+","("),输出现为"9"

  (4)第四个字符是数字3,直接输出,3后面是运算符"-","-“号进栈,栈中现有(”+","(","-"),输出现为"9 3"

  (5)接下来是数字1,直接输出,后面是符号")",此时,这个反括号就i要去栈中匹配正括号了,在两个括号中间的元素依次出栈,")“入栈后,栈中元素为(”+","(","-",")"),两个括号中间的元素为"-",将"-“号输出,执行完后,栈中还有(”+"),输出为"9 3 1 -"

  (6)接着是运算符"×",此时栈顶元素为"+","+" 的优先级是低于 " ×"的 ,所以不输出,“×"直接进栈,紧接着是数字3,直接输出,现在栈中元素为(”+"," × “),输出为"9 3 1 - 3”

  (7)之后是运算符"+",此时当前栈顶元素为符号"+",“×"是比” + “的优先级高的,所以栈中元素全部出栈并输出,然后把当前元素入栈(注意前几步栈中的的"+“是中缀表达式开头,数字9后面的”+",现在这个"+"是"9+(3-1)×3"和"10÷2"中间的加号),此时总输出为"9 3 1 - 3 × + “,栈中有(”+”)

  (8)紧接着是数字10,直接输出,总输出为"9 3 1 - 3 × + 10"。后面是符号"/",直接入栈,栈中现有("+","/")。

  (9)最后一个元素是数字2,直接输出,因为是最后一个元素了,栈中元素依次出栈拼接在数字2的后面,现在栈是空的,总输出为"9 3 1 - 3 × + 10 2 / +"

  小结


  从上面的推导中,可以发现,整个运算过程都运用了栈先进后出,后进先出的特性,理解好逆波兰式也就理解好了栈这个数据结构。

  我发言完毕~
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值