zoukankan      html  css  js  c++  java
  • 逆波兰算法-python代码实现

    1,逆波兰算法简介

    假定给定一个只 包含 加、减、乘、除,和括号的算术表达式,你怎么编写程序计算出其结果?

    问题是:在表达式中,括号,以及括号的多层嵌套 的使用,运算符的优先级不同等因素,使得一个算术表达式在计算时,运算顺序往往因表达式的内容而定,不具规律性。 这样很难编写出统一的计算指令。
    使用逆波兰算法可以轻松解决这个问题。他的核心思想是将普通的中缀表达式转换为后缀表达式。

    什么是中缀表达式?例如a+b,运算符在两个操作数的中间。这是我们从小学开始学习数学就一直使用的表达式形式。

    什么是后缀表达式?例如a b + ,运算符在两个操作数的后面。后缀表达式虽然看起来奇怪,不利于人阅读,但利于计算机处理。

    转换为后缀表达式的好处是:
    1、去除原来表达式中的括号,因为括号只指示运算顺序,不是实际参与计算的元素。
    2、使得运算顺序有规律可寻,计算机能编写出代码完成计算。

    2,逆波兰算法原理

    逆波兰算法的核心步骤就2个:
    1、将中缀表达式转换为后缀表达式,例如输入的原始表达式是 3*(5+7) ,转换得到 3 5 7 + *
    2、根据后缀表达式,按照特定的计算规则得到最终计算结果

    下面详细介绍这个2步的操作。

    中缀表达式转换为后缀表达式
    你需要设定一个栈SOP,和一个线性表 L 。SOP用于临时存储运算符和左括号分界符( ,L用于存储后缀表达式。
    遍历原始表达式中的每一个表达式元素
    (1)如果是操作数,则直接追加到 L中。只有 运算符 或者 分界符( 才可以存放到 栈SOP中
    (2)如果是分界符
             Ⅰ 如果是左括号 ( , 则 直接压入SOP,等待下一个最近的 右括号 与之配对。
              Ⅱ 如果是右括号),则说明有一对括号已经配对(在表达式输入无误的情况下)。不将它压栈,丢弃它,然后从SOP中出栈,得到元素e,将e依次追加到L里。一直循环,直到出栈元素e 是 左括号 ( ,同样丢弃他。
    (3)如果是运算符(用op1表示)
            Ⅰ如果SOP栈顶元素(用op2表示) 不是运算符,则二者没有可比性,则直接将此运算符op1压栈。 例如栈顶是左括号 ( ,或者栈为空。
             Ⅱ 如果SOP栈顶元素(用op2表示) 是运算符 ,则比较op1和 op2的优先级。如果op1 > op2 ,则直接将此运算符op1压栈。
    如果不满足op1 > op2,则将op2出栈,并追加到L,再试图将op1压栈,如果如果依然不满足 op1>新的栈顶op2,继续将新的op2弹出追加到L ,直到op1可以压入栈中为止。
    也就是说,如果在SOP栈中,有2个相邻的元素都是运算符,则他们必须满足:下层运算符的优先级一定小于上层元素的优先级,才能相邻。

    最后,如果SOP中还有元素,则依次弹出追加到L后,就得到了后缀表达式。

    3,应用

    请写一个整数计算器,支持加减乘除三种运算和括号。

    输入
    
    "1+2"
    
    输出
    
    3
    
    输入
    
    "(2*(3-4))*5"
    
    输出
    
    -10

    python 代码实现:

    class Solution:
        def __init__(self):
            self.Operator_priority = {
                "+": 0,
                "-": 0,
                "*": 1,
                "/": 1
            }
            self.Operator = ["+""-""*""/"]
            self.DemarcationSymbol = ["("")"]
            self.L = []
            self.stack = []
    
        def solve(self, s):
            self.infixToSuffix(s)
            return self.suffixToResult(self.L)
    
    
        def changeTypeofExpression(self, expression):
            temp_expression = []
            temp_num ""
            for exp in expression:
                if exp.isdigit():
                    temp_num += exp
                    continue
                else:
                    temp_expression.append(temp_num)
                    temp_num ""
                    temp_expression.append(exp)
            temp_expression.append(temp_num)
            return temp_expression
    
    
        def infixToSuffix(self, expression):
            temp_expression = self.changeTypeofExpression(expression)
            for item in temp_expression:
                if item.isdigit():
                    self.L.append(item)
                elif item in self.Operator:  # 判断是否是操作符
                    while len(self.stack) != 0 and self.stack[-1] in self.Operator and self.Operator_priority[item] <= self.Operator_priority[self.stack[-1]]:
                        self.L.append(self.stack.pop())
                    self.stack.append(item)
    
    
                elif item in self.DemarcationSymbol:  # 判断是否是分隔符
                    if item == "(":
                        self.stack.append(item)
                    elif item == ")":
                        while len(self.stack) != 0 and self.stack[-1] != "(":
                            self.L.append(self.stack.pop())
                        if len(self.stack) != 0:
                            self.stack.pop()
    
    
            while len(self.stack) != 0:
                self.L.append(self.stack.pop())
    
    
        def suffixToResult(self, suffix_expression):
            for item in suffix_expression:
                if item.isdigit():  # 如果是数字就添加到stack中去
                    self.stack.append(item)
                elif item in self.Operator:
                    num1 = self.stack.pop()
                    num2 = self.stack.pop()
                    temp_value = self.Calculation(float(num2), float(num1), item)
                    self.stack.append(temp_value)
            return self.stack.pop()
    
    
        def Calculation(self, num1, num2, op):
            if op == "+":
                return num1+num2
            elif op == "-":
                return num1-num2
            elif op == "*":
                return num1*num2
            else:
                return num1/num2
    
    
    if __name__ == "__main__":
        s = Solution()
        print(s.solve("(100+100)*100"))
    不论你在什么时候开始,重要的是开始之后就不要停止。 不论你在什么时候结束,重要的是结束之后就不要悔恨。
  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    《EffectiveJava中文第二版》 高清PDF下载
    《MoreEffectiveC++中文版》 pdf 下载
    《啊哈c语言》 高清 PDF 下载
  • 原文地址:https://www.cnblogs.com/yunhgu/p/13885680.html
Copyright © 2011-2022 走看看