Infix到Postfix Python:IndexError:从空列表中弹出。不在多个数字上工作

时间:2017-03-11 13:06:15

标签: python stack

我的代码:

from StackClass import Stack


def postfixEval(postfix):
    os = Stack()

    tokenList = postfix

    for token in tokenList:
        if token in "0123456789":
            os.push(int(token))
        else:
            op2 = os.pop()
            op1 = os.pop()
            result = doMath(token,op1,op2)
            os.push(result)
    return os.pop()

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 pres(p):
    if p is '(':
        return 0
    elif p is '+' or '-':
        return 1
    elif p is '*' or '/':
        return 2
    else:
        return 99

def read(p):
    if p is '(':
        return left
    elif p is ')':
        return right
    elif p is '+' or p is '-' or p is '*' or p is '%' or p is '/':
        return operator
    elif p is ' ':
        return empty    
    else :
        return operand                          




def infixtopostfix(infixexp):

    for i in infixexp :
        type = read(i)
        if type is left :
            outlst.append(i)
        elif type is right :
            next = outlst.pop()
            while next is not '(':
                postfix.append(next)
                next = outlst.pop()
        elif type is operand:
            postfix.append(i)
        elif type is operator:
            p = pres(i)
            while len(outlst) is not 0 and p <= pres(outlst[-1]) :
                postfix.append(outlst.pop())
            outlst.append(i)
        elif type is empty:
            continue

    while len(outlst) > 0 :
        postfix.append(outlst.pop())
    return " ".join(postfix)












#MAIN PROGRAM


while True:



    postfix = []
    outlst = []
    operator = -10
    operand = -20
    left = -30
    right = -40
    empty = -50


    infixexp = raw_input("\nEnter the infix notation : ")
    ifx = infixexp.split()
    showpfx = infixtopostfix(ifx)

    print "\nIt's postfix notation is \n"
    print(showpfx) 

    print "\nThe answer to the postfix notation is: \n"
    pfx = showpfx.split()
    print postfixEval(pfx)  



    choice = raw_input("\nDo you want to continue?<1-Yes/0-No>: ")

    if choice == '0':
        break

这适用于(1 + 3)* 5但在(500 + 500)* 1000上出现此错误:

> Traceback (most recent call last):   File "practice.py", line 117, in
> <module>
>     print postfixEval(pfx)   File "practice.py", line 13, in postfixEval
>     op2 = os.pop()   File "C:\Python27\StackClass.py", line 16, in pop
>     return self.items.pop() IndexError: pop from empty list

返回后缀值后,我再次将其拆分,然后将其插入评估函数。它适用于1位数字,但不适用于3位数字。有什么想法错了吗?谢谢!

1 个答案:

答案 0 :(得分:0)

if token in "0123456789":

仅匹配"0123456789"的子字符串,例如单个数字12789 ...检查实数正整数的实际方法是:

if token.isdigits():

(如果已经处理了负数,那么尝试转换为整数并捕获ValueError

BIG旁白:虽然我很喜欢,但我最好告诉你接下来会失败的代码:

is正在比较引用。虽然字符串实习适用于短字符串,但我不会依赖它。请改用==

pres还有另一个严重问题:

elif p is '+' or '-':

正在检查p是否为+,但如果不是,则会测试-是否为“真”,这是......总是如此。所以你的情况总是如此。

在字符串上用in重写它:

def pres(p):
    if p == '(':
        return 0
    elif p in '+-':
        return 1
    elif p in '*/':
        return 2
    else:
        return 99

并取消所有is测试,转而使用==。这样可以避免意外(例如None这样的单例对象is是惯用的)

注意:在read中你是对的(is部分除外):

elif p is '+' or p is '-' or p is '*' or p is '%' or p is '/':

但当然它写得更短更好:

elif p in '+-*%/':