波兰表示法和逆波兰表示法

一、简介 波兰表示法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 ''

 

     

posted @ 2018-02-08 20:26  南石  阅读(2188)  评论(0编辑  收藏  举报