[新手学数据结构]波兰表示法与逆波兰表示法


知识背景

    通俗下对于9+1这样的表达式我们一般称做为中缀表示法(下文称为普通表示法),那么可想而知,有中缀表示法就有前缀表示法和后缀表示法。这两个概念其实是一位波兰的数学家扬·武卡谢维奇在1920年引入的新的概念:
    在书中它本人提到:

“ 我在1924年突然有了一个无需括号的表达方法,我在文章第一次使用了这种表示法。 ”
                                                                     —— Łukasiewicz(1), p. 610, footnote.

    这两中表示法被称为波兰表示法和逆波兰表示法。

正文

    举个栗子:1+2
    我们通常的计算表示方法是:1+2=3;但是波兰表示法确不是这样:+12(前缀表示法又称为波兰表示法),12+(后缀表示法又称为逆波兰表示法);波兰表示法与普通表示法能够计算机能够快速解析,在上面这个例子中看不出解析问题出来。但是当计算带有括号的表达式的时候就会出现这很明显的解析性能问题。

    例如:(3-2)*7,假如采用普通表达式来分析我们就需要先考虑优先级。先计算括号里面的再相乘。这个对于人来说很简单,但对于计算机而言就有点很困难。因为在操作符里面计算机根本不知道括号里面的优先级高于括号外面的。那么这个时候波兰表示法就开始发挥了作用。波兰表示法表示为:*-567;逆波兰表示法表示为56-7*.(下面会详细介绍)。然后再利用栈来解决这个问题;计算机主要使用逆波兰表示法,因为试想当你在进行一个表达式计算的时候会开始就计算一个操作符吗?第一个肯定是一个操作数。

    前缀法和后缀法两者的计算方法是相同的:对于一个表达式从左读到右遇到两个的连续的操作数并且这俩个连续的操作数后跟有操作符那么就运算,每次运行一项(一步一步来的,计算机不会跳跃思维)。举个维基百科中的例子(前缀表示法):

 - * / 15 - 7 + 1 1 3 + 2 + 1 1 =
 - * / 15 - 7     2 3 + 2 + 1 1 =
 - * / 15     5 3 + 2 + 1 1 =
 - *        3       3 + 2 + 1 1 =
 -          9         + 2 + 1 1 =
 -          9 + 2             2 =  
 -          9                 4 =
            5 

那么如何把一个数学表达式转化为计算机能够解析使用的逆波兰表示法?

    

    譬如:1-2*3*4+5*(7-6)+8
    逆波兰表示法:1234**-576-*8++
    通过逆波兰式先计算:
    1、   1234**-576-*8++————1234**-51*8++
    2、   1234**-51*8++——————1234**-58++
    3、   1234**-58++——————1234**-13+
    4、   1234**-13+———————1212*-13+
    5、   1212*-13+———————124-13+
    6、   -124-13+————————-2313+
    7、   -2313+——————————-10 

    大概就是上面的一个意思,然后通过计算机来实现数学表达式的计算,之前有提到过利用堆栈来解决;具体的步骤是:操作数入栈;遇到操作符时,操作数出栈,求值,将结果入栈;当一遍后,栈顶就是表达式的值。因此逆波兰表达式的求值使用堆栈结构很容易实现,和能很快求值。(这是逆波兰的解析过程)

 逆波兰表达式的求值:

    伪代码

  • while有输入符号可以用一个数组来保存一段表达式来计算
    • 读入输入的一个符号
    • IF是一个操作数
      • 入栈
    • ELSE IF是一个操作符
      • 有一个先验的表格给出该操作符需要n个参数
      • IF堆栈中少于n个操作数
        • (错误) 用户没有输入足够的操作数
      • Else,n个操作数出栈
      • 计算操作符。
      • 将计算所得的值入栈
  • IF栈内只有一个值
    • 这个值就是整个计算式的结果
  • ELSE多于一个值
    • (错误) 用户输入了多余的操作数

举个栗子:9-2*(3-2)+5

  1. 9————————入栈         (堆栈中:9)
  2. 2————————入栈         (堆栈中:9,2) 
  3. 3————————入栈         (堆栈中:9,2,3)  
  4. 2————————入栈         (堆栈中:9,2,3,2)
  5. -————————入栈          (堆栈中:9,2,结果1入栈)
  6. *————————入栈          (堆栈中:9,结果2入栈)
  7. -————————入栈           (堆栈中:结果7入栈)
  8. 5————————入栈           (堆栈中:7,5)
  9. +————————入栈            (堆栈中:12)

注:在进行运算时有操作数以及操作符出栈

参考资料:http://zh.wikipedia.org/wiki/波兰表示法

你可能感兴趣的:([新手学数据结构]波兰表示法与逆波兰表示法)