波蘭表示法和逆波蘭表示法


一、簡介 波蘭表示法Polish notation,或波蘭記法),是一種邏輯、算術和代數表示方法,其特點是操作符置於操作數的前面,因此也稱做前綴表示法。如果操作符的元數(arity)是固定的,則語法上不需要括號仍然能被無歧義地解析。波蘭記法是波蘭數學家揚·武卡謝維奇1920年代引入的,用於簡化命題邏輯。

揚·武卡謝維奇本人提到:

我在1924年突然有了一個無需括號的表達方法,我在文章第一次使用了這種表示法。
— Łukasiewicz(1), p. 610, footnote.

阿隆佐·邱奇在他的經典著作《數理邏輯》中提出該表達方法是一種值得被關注的記法系統,甚至將它與阿弗烈·諾夫·懷海德和伯特蘭·羅素在《數學原理》中的邏輯表達式相提並論。 逆波蘭表示法Reverse Polish notationRPN,或逆波蘭記法),是一種是由波蘭數學家揚·武卡謝維奇1920年引入的數學表達式方式,在逆波蘭記法中,所有操作符置於操作數的后面,因此也被稱為后綴表示法。逆波蘭記法不需要括號來標識操作符的優先級。 逆波蘭結構由弗里德里希·鮑爾(Friedrich L. Bauer)和艾茲格·迪科斯徹在1960年代早期提議用於表達式求值,以利用堆棧結構減少計算機內存訪問。逆波蘭記法和相應的算法由澳大利亞哲學家、計算機學家查爾斯·漢布林(Charles Hamblin)在1960年代中期擴充 在1960和1970年代,逆波蘭記法廣泛地被用於台式計算器,因此也在普通公眾(工程、商業和金融領域)中使用。 下面大部分是關於二元運算,一個一元運算使用逆波蘭記法的例子是階乘的記法。 二、中綴表達式到前綴和后綴表達式轉換過程 波蘭表示法(中綴表達式轉換成前綴表達式算法)

  • 首先設定一個操作符棧,從右到左順序掃描整個中綴表達式,如果是操作數,則直接歸入前綴表達式;
  • 如果是操作符,則檢測器是否是右括號,如果是右括號,則直接將其入棧;
  • 如果是左括號,則將棧中的操作符依次彈棧,歸入前綴表達式,直至遇到右括號,將右括號彈棧,處理結束;
  • 如果是其他操作符,則檢測棧頂操作符的優先級與當前操作符的優先級關系,
  • 如果棧頂操作符優先級大於當前操作符的優先級,則彈棧,並歸入前綴表達式,直至棧頂操作符優先級小於等於當前操作符優先級,這時將當前操作符壓棧。
  • 當掃描完畢整個中綴表達式后,檢測操作符棧是否為空,如果不為空,則依次將棧中操作符彈棧,歸入前綴表達式。最后,將前綴表達式翻轉,得到中綴表達式對應的前綴表達式。

逆波蘭表示法(中綴表達式轉換成后綴表達式算法)

  • 從左至右掃描一中綴表達式;
  • 若讀取的是操作數,則判斷該操作數的類型,並將該操作數存入操作數堆棧;
  • 若讀取的是運算符:
1. 該運算符為左括號"(",則直接存入運算符堆棧;
2. 該運算符為右括號")",則輸出運算符堆棧中的運算符到操作數堆棧,直到遇到左括號為止;
3.該運算符為非括號運算符:
(1) 若運算符堆棧棧頂的運算符為括號,則直接存入運算符堆棧。
(2) 若比運算符堆棧棧頂的運算符優先級高或相等,則直接存入運算符堆棧。
(3) 若比運算符堆棧棧頂的運算符優先級低,則輸出棧頂運算符到操作數堆棧,並將當前運算符壓入運算符堆棧
  • 當表達式讀取完成后運算符堆棧中尚有運算符時,則依序取出運算符到操作數堆棧,直到運算符堆棧為空。

三、 對波蘭表達式和逆波蘭表達式求解過程 波蘭表示法

  • 從右到左依次掃描語法單元的項目。
  • 如果掃描的項目是操作數,則將其壓入操作數堆棧,並掃描下一個項目。
  • 如果掃描的項目是一個二元運算符,則對棧的頂上兩個操作數執行該運算。
  • 如果掃描的項目是一個一元運算符,則對棧的最頂上操作數執行該運算。
  • 將運算結果重新壓入堆棧。
  • 重復步驟第2-5步,堆棧中即為結果值。
 
逆波蘭表示法
 
  • 從左到右依次掃描語法單元的項目。
  • 如果掃描的項目是操作數,則將其壓入操作數堆棧,並掃描下一個項目。
  • 如果掃描的項目是一個二元運算符,則對棧的頂上兩個操作數執行該運算。
  • 如果掃描的項目是一個一元運算符,則對棧的最頂上操作數執行該運算。
  • 將運算結果重新壓入堆棧。
  • 重復步驟第2-5步,堆棧中即為結果值。
四、 中綴表達式到前綴和后綴表達式轉換過程(Python實現) 基礎程序
 1 class Element(object):
 2     '單個Element可以表示一個操作數或運算符.'
 3     '_vtype = 0 - none,  _vtype = 1 - 操作數, _vtype = 2 - 運算符'
 4 
 5     def __init__(self, vtype, value) :
 6         if type(vtype) == int and type(value) == str :
 7             self._vtype = vtype
 8             self._value = value
 9         
10     def setType(self, vtype) :
11         if type(vtype) == int :
12             self._vtype = vtype
13             return 0
14         else :
15             return 1
16 
17     def setValue(self, value) :
18         if type(value) == str :
19             self._value = value
20             return 0
21         else :
22             return 1
23 
24     def setTypeAndValue(self, vtype, value) :
25         if type(vtype) == int and type(value) == str :
26             self.setType(vtype)
27             self.setValue(value)
28             return 0
29         else :
30             return 1
31 
32     def getType(self) :
33         return self._vtype
34 
35     def getValue(self) :
36         return self._value
37 
38 class Stack(object):
39     ''
40     # initialze the stack
41     def __init__(self) :
42         self.items = []
43 
44     # judge the stack is empty
45     def isEmpty(self) :
46         return self.items == []
47 
48     # return the top element
49     def peek(self) :
50         return self.items[len(self.items) - 1]
51 
52     # return the size of stack
53     def size(self) :
54         return len(self.items)
55 
56     # push element into stack
57     def push(self, item) :
58         self.items.append(item)
59 
60     # pop the top element
61     def pop(self) :
62         return self.items.pop()

 

  波蘭表示法
 1 def convertInfixToPrefix(infixExp) :
 2     '將中綴表達式轉換為前綴表達式'
 3     expLen = len(infixExp)
 4     if type(infixExp) == str and expLen > 0 :
 5         #操作數堆棧
 6         operandStack = Stack()
 7         #運算符堆棧
 8         operatorStack = Stack()
 9         index = expLen - 1
10         while index >= 0 :
11             if infixExp[index] == ')' :
12                 operatorStack.push(Element(2, infixExp[index]))
13             elif infixExp[index] == '(' :
14                 while not operatorStack.isEmpty() :
15                     elem = operatorStack.peek()
16                     if elem.getType() == 2 :
17                         if elem.getValue() == ')' :
18                             operatorStack.pop()
19                             break;
20                         else :
21                             operandStack.push(operatorStack.pop())
22                     else :
23                         continue;
24             elif optPriority(infixExp[index]) > 0 :    # + - * / % 運算符
25                 if not operatorStack.isEmpty() :
26                     elem = operatorStack.peek()
27                     if elem.getType() == 2 :
28                         if elem.getValue() == ')':
29                             operatorStack.push(Element(2, infixExp[index]))
30                         elif optPriority(infixExp[index]) > optPriority(elem.getValue()) :
31                             operatorStack.push(Element(2, infixExp[index]))
32                         else :
33                             operandStack.push(operatorStack.pop())
34                             operatorStack.push(Element(2, infixExp[index]))
35                 else :
36                     operatorStack.push(Element(2, infixExp[index]))
37             elif infixExp[index].isdecimal() :        # 數字
38                 if index < expLen - 1 and infixExp[index + 1].isdecimal() and not operandStack.isEmpty() :
39                     elem = operandStack.pop()
40                     elem.setValue(infixExp[index] + elem.getValue())
41                     operandStack.push(elem)
42                     
43                 else :
44                     operandStack.push(Element(1, infixExp[index]))
45             else :
46                 pass
47             index = index - 1
48         while not operatorStack.isEmpty() : #檢查運算符堆棧是否為空
49             operandStack.push(operatorStack.pop())
50             
51         result = ''
52         while not operandStack.isEmpty() :
53             elem = operandStack.pop()
54             result = result + ' ' + elem.getValue();
55         return result
56     else :
57         return ''

 

逆波蘭表示法

 1 def convertInfixToSuffix(infixExp) :
 2     '將中綴表達式轉換為后綴表達式'
 3     expLen = len(infixExp)
 4     if type(infixExp) == str and expLen > 0 :
 5         #操作數堆棧
 6         operandStack = Stack()
 7         #運算符堆棧
 8         operatorStack = Stack()
 9         for index in range(expLen) :
10             if infixExp[index] == '(' :    # 左括號
11                 operatorStack.push(Element(2, infixExp[index]))
12                 
13             elif infixExp[index] == ')' :  # 右括號
14                 while not operatorStack.isEmpty() :
15                     elem = operatorStack.peek()
16                     if elem.getType() == 2 :
17                         if elem.getValue() == '(' :
18                             operatorStack.pop()
19                             break;
20                         else :
21                             operandStack.push(operatorStack.pop())
22                     else :
23                         continue;
24                         
25             elif optPriority(infixExp[index]) > 0 :    # + - * / % 運算符
26                 if not operatorStack.isEmpty() :
27                     elem = operatorStack.peek()
28                     if elem.getType() == 2 :
29                         if elem.getValue() == '(':
30                             operatorStack.push(Element(2, infixExp[index]))
31                         elif optPriority(infixExp[index]) > optPriority(elem.getValue()) :
32                             operatorStack.push(Element(2, infixExp[index]))
33                         else :
34                             operandStack.push(operatorStack.pop())
35                             operatorStack.push(Element(2, infixExp[index]))
36                 else :
37                     operatorStack.push(Element(2, infixExp[index]))
38                     
39             elif infixExp[index].isdecimal() :        # 數字
40                 if index > 0 and infixExp[index - 1].isdecimal() and not operandStack.isEmpty() :
41                     elem = operandStack.pop()
42                     elem.setValue(elem.getValue() + infixExp[index])
43                     operandStack.push(elem)
44                     
45                 else :
46                     operandStack.push(Element(1, infixExp[index]))
47             else :
48                 pass
49         while not operatorStack.isEmpty() : #檢查運算符堆棧是否為空
50             operandStack.push(operatorStack.pop())
51             
52         result = ''
53         while not operandStack.isEmpty() :
54             elem = operandStack.pop()
55             result = elem.getValue() + ' ' + result;
56         return result
57     else :
58         return ''

 

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM