python中序表达式转为后序


1.   先了解后序表达式的计算

ABC*+

对于这样的式子,数字依次入栈,如果遇到操作符,从栈中弹出两个数进行相应的计算,并将结果入栈,接着继续取表达式中的元素,重复该步骤,直到表达式被取完,栈中元素结尾结果。

2.   中序变后序表达式

确保结果列表中原来表达式里优先级高的在后序表达式的靠左侧

方法:

有 1 个结果列表,1 个栈

先将字符串拆成列表

遍历列表:

  数字放入结果列表,不管何种表达式不影响数字的顺序

  遇运算符,如果栈中已有运算符优先级大于等于当前运算符,则栈中运算符加入结果列表(同级运算符顺序计算);运算符入栈

  最后将栈中运算符依次出栈并加至结果列表的末尾

至此可以解决A*B+C、和A+B*C的问题

下面解决括号改变优先级的问题

在遍历中加一个检测:

左括号入栈;如果读到右括号,则将栈中的元素添加到结果列表中,直到左括号为止

3.   python中栈的使用

使用列表,在尾部添加或移除,取栈顶元素使用mystack[-1],

判空直接使用名字

import string

def infixToPostfix(infixexpr):

    prec = {}
    prec['*'] = 3
    prec['/'] = 3
    prec['+'] = 2
    prec['-'] = 2
    prec['('] = 1

    opStack = []
    postfixList = []
    tokenList = infixexpr.split()

    for token in tokenList:
        if token in string.ascii_uppercase:#数字
            postfixList.append(token)
        elif token == '(':#左括号入栈
            opStack.append(token)
        elif token == ')':#右括号
            topToken = opStack.pop()
            while topToken != '(':
                postfixList.append(topToken)
                topToken = opStack.pop()
        else:
            while opStack and \
                      (prec[opStack[-1]] >= prec[token]):
                postfixList.append(opStack.pop())
            opStack.append(token)
    while opStack:
        postfixList.append(opStack.pop())
    return ' '.join(postfixList)

s = input()
print(infixToPostfix(s))

加入计算功能:

import string

def doMath(op,op1,op2):
    if op == '*':
        return op1*op2
    elif op == '/':
        return op1/op2
    elif op == '+':
        return op1+op2
    else:
        return op1-op2

def infixToPostfix(infixexpr):
    prec = {}
    prec['*'] = 3
    prec['/'] = 3
    prec['+'] = 2
    prec['-'] = 2
    prec['('] = 1

    opStack = []
    postfixList = []
    tokenList = infixexpr.split()
    for token in tokenList:
        if token not in '+-*/()':#数字
            postfixList.append(token)
        elif token == '(':#左括号入栈
            opStack.append(token)
        elif token == ')':#右括号
            topToken = opStack.pop()
            while topToken != '(':
                postfixList.append(topToken)
                topToken = opStack.pop()
        else:
            while opStack and \
                      (prec[opStack[-1]] >= prec[token]):
                postfixList.append(opStack.pop())
            opStack.append(token)
    while opStack:
        postfixList.append(opStack.pop())
    return ' '.join(postfixList)

def postfixEval(postfixExpr):
    operandS = []
    tokenList = postfixExpr.split()
    for token in tokenList:
        if token not in '+-*/':
            operandS.append(float(token))
        else:
            operand2 = operandS.pop()
            operand1 = operandS.pop()
            result = doMath(token,operand1,operand2)
            operandS.append(result)
    return operandS.pop()

ch = 'y'
while ch == 'y':
    s = input()
    print(postfixEval(infixToPostfix(s)))
    ch = input('Continue? y/n ')

4.   错误检测和报告

两大函数组合一下,使用异常处理,如果制作后序表达式时出问题,抛出异常,不再计算后面的值