zoukankan      html  css  js  c++  java
  • 波兰表示法和逆波兰表示法

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

         

  • 相关阅读:
    gsm at 指令
    wm8976 codec
    【Gym 100971J】Robots at Warehouse
    【XDU1144】合并模板
    腾讯云CentOS7安装LNMP+wordpress
    【USACO1.1】Broken Necklace
    【校赛小分队之我们有个女生】训练赛6
    【计导作业】——商品记录
    C 文件读写2
    C 文件读写1
  • 原文地址:https://www.cnblogs.com/aspiration2016/p/8433058.html
Copyright © 2011-2022 走看看