表达式求值

前缀表达式: \(-*+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 )"))
posted @ 2021-10-19 17:01  爱吃西瓜的菜鸟  阅读(210)  评论(0编辑  收藏  举报