zoukankan      html  css  js  c++  java
  • 表达式求值

    前缀表达式: (-*+ABC*-DE+FG)

    中缀表示式:((((A+B)*C)-((D-E)*(F+G))))

    后缀表达式:(AB+C*DE-FG+*-)

    1 前缀表达式求解

    操作符直接放入栈,遇到数字就弹出数字和符号进行计算,把计算的结果再放入栈

    def pre_value(s):
        s = s.split()
        operate_stack = []
        for token in s:
            if token in "+/*-":
                operate_stack.append(token)
            else:
                if operate_stack[-1] in "+-*/":
                    operate_stack.append(token)
                else:
                    
                    while len(operate_stack)>1 and operate_stack[-1] not in "+-*/":
                        num = operate_stack.pop()
                        operate = operate_stack.pop()
                        if operate=="+":
                            token = float(num) + float(token)
                        elif operate=="-":
                            token = float(num)-float(token)
                        elif operate=="*":
                            token = float(num)*float(token)
                        elif operate=="/":
                            token = float(num)/float(token)
                    operate_stack.append(str(token))
        return operate_stack.pop()
    print(pre_value('/ + 7 8 + 3 2'))  
    print(pre_value('+ * 7 8 * 3 2'))
    print(pre_value('- * + 7 8 3 * - 2 9 + 1 5'))
    print(pre_value('- * + 7 * 8 3 3 * - 2 9 + 1 5'))
    

    2 后缀表达式求值

    让数字进栈,遇见操作符之后弹出两个数字进行运算后,将数字放入栈

    def end_value(s):
        s = s.split()
        stack = []
        for token in s:
            if token.isdigit():
                stack.append(token)
            else:
                num2 = stack.pop()
                num1 = stack.pop()
                if token=="+":
                    stack.append(str(float(num1)+float(num2)))
                elif token == "-":
                    stack.append(str(float(num1)-float(num2)))
                elif token=="*":
                    stack.append(str(float(num1)*float(num2)))
                else:
                    stack.append(str(float(num1)/float(num2)))
        return stack.pop()
    
    print(end_value('7 8 + 3 2 + /'))
    print(end_value("7 8 * 3 2 * +"))
    print(end_value("7 8 + 3 * 2 9 - 1 5 + * -"))
    print(end_value("7 8 3 * + 3 * 2 9 - 1 5 + * -"))   
    

    3 中缀表达式求值

    中缀表达式一般都是转化成前缀表达式或者后缀表达式进行求解

    3.1 中缀表达式转换成前缀表达式

    从右到左(反转)遍历中缀表达式,遇到操作数(字母及数字),则输出;遇到")",则进栈;遇到"(",则弹出栈顶,若栈顶不为")“则输出,继续弹出下一个栈顶并比较,直到弹出”)",结束循环;遇到运算符,若栈不为空,且栈顶元素的优先级>=运算符的优先级(表明栈顶元素也是运算符,这2个运算符相邻),弹出并输出栈顶元素,继续循环比较,直到不符合循环条件,再将该运算符入栈;遍历结束后,若栈仍不为空,则依次弹出并输出,将最终输出连接并返回结果。

    def mid2pre(s):
        s = s.split()[::-1]
        stack = []
        res = []
        for token in s:
            if token==")":
                stack.append(token)
            elif token.isdigit() or token.isalpha():
                res.append(token)
            elif token=="(":
                while stack and stack[-1]!=")":
                    res.append(stack.pop())
                if stack:
                    stack.pop()
            elif token in "+-*/":
                if token in "+-":
                    while stack and stack[-1] in "+-*/":
                        res.append(stack.pop())
                    stack.append(token)
                else:
                    while stack and stack[-1] in "*/":
                        res.append(stack.pop())
                    stack.append(token)
        while stack:
            res.append(stack.pop())
        return "".join(res[::-1])
    

    3.2 中缀表达式转换成后缀表达式

    从左到右遍历中缀表达式,遇到操作数(字母及数字),则输出;遇到"(",则进栈;遇到")",则弹出栈顶,若栈顶不为"(“则输出,继续弹出下一个栈顶并比较,直到弹出”(",结束循环;遇到运算符,若栈不为空,且栈顶元素的优先级>=运算符的优先级(表明栈顶元素也是运算符,这2个运算符相邻),弹出并输出栈顶元素,继续循环比较,直到不符合循环条件,再将该运算符入栈;遍历结束后,若栈仍不为空,则依次弹出并输出,将最终输出连接并返回结果。

    def mid2end(s):
        s = s.split()
        stack = []
        res = []
        for token in s:
            if token.isdigit() or token.isalpha():
                res.append(token)
            elif token == "(":
                stack.append(token)
            elif token in "+-*/":
                if token in "+-":
                    while stack and stack[-1] in "+-*/":
                        res.append(stack.pop())
                    stack.append(token)
                else:
                    while stack and stack[-1] in "*/":
                        res.append(stack.pop())
                    stack.append(token)
            elif token==")":
                while stack and stack[-1]!="(":
                    res.append(stack.pop())
                stack.pop()
        while stack:
            res.append(stack.pop())
        return res
    
    print(mid2end("A * B + C * D"))
    print(mid2end("( A + B ) * C - ( D - E ) * ( F + G )"))
    print(mid2end("( A + B * C ) * C - ( D - E ) * ( F + G )"))
    
  • 相关阅读:
    FreeMarker的<#if></#if>标签
    ubuntu的dpkg命令安装和卸载软件
    ubuntu建立软链接注意事项
    halo的工作目录,有一个是在代码里配置的,硬编码了
    Springboot的多环境配置
    idea中的springboot+gradle项目报错springboot configuration annotation processor not found in classpath
    maven中的pom.xml中的scope的作用
    设置idea的快捷键组合 设置为默认
    springboot无法查询到后台的数据
    ssh互信条件下的多机拷贝脚本和执行远程命令
  • 原文地址:https://www.cnblogs.com/zhou-lin/p/15425514.html
Copyright © 2011-2022 走看看