Python堆栈超出界限错误

时间:2015-04-09 07:20:26

标签: python list stack indexoutofboundsexception

我在push方法的堆栈中得到索引超出范围的错误。

我正在尝试在python中实现一个后缀样式逻辑计算器。例如,0!1&1!0=!1/|将评估为1或为真。

我使用堆栈和与这样的列表“push”和“pop”相关联的常用方法来实现它但是我不允许使用典型的append或remove方法,在这种实现中可能没问题。相反,我必须将列表启动到标准大小,该大小等于我将执行评估的表达式的长度。

我使用名为evaluate的方法执行此操作,方法是引用一个名为top的全局整数,该整数指向堆栈的顶部,并根据我是否调用{{1}递增或递减}或push

我的pop方法如下

push

我的def push(stack, element): global tos tos += 1 stack[tos] = element 方法如下

pop

基本上,我使用

读取字符串的每个单独元素
def pop(stack):
    #stack = None
    global tos
    tos -= 1

然后我说,for i in expression (某种表达方式):执行预制方法。

以下是我在此循环中找到的代码中的几个示例,它遍历表达式

if i ==

我测试了if op == "1": push(theStack, True) elif op == "0": push(theStack, False) elif op == "!": pop(None) push(theStack, Not(theStack[tos])) elif op == "&": pop(None) pop(None) push(theStack, And(theStack[tos], theStack[tos + 1])) ,它看起来应该做什么。我认为错误在于pop

我将push发起为-1,这也是我方法顶部的快速峰值,可以在

中找到循环
tos

我不会在def LogicalEval (expression): global tos theStack = [len(expression)] def Not(expr): if expr == True: return False else: return True def And (expr1, expr2): if expr1 == True and expr2 == True: return True else: return False 之外的任何位置启动堆栈,实际上我只限于三种主要方法(LogicalEvalpushpop)在LogicalEval

中找到的AndNot辅助方法之外的方法

2 个答案:

答案 0 :(得分:3)

您使用一个元素创建了一个堆栈:

theStack = [len(expression)]

len()返回一个整数,所以在给定5个charcaters的表达式的情况下,您创建了以下列表:

theStack = [5]

所以你快速用完空间。

像这样创建列表:

theStack = [None] * len(expression)

序列上的乘法重复该序列。 [None]是一个包含一个元素的列表(None sentinel值),并乘以表达式的长度创建一个包含许多元素的列表。

接下来,您对!&的堆栈操作数的处理不正确:

elif op == "!":
    pop(None)
    push(theStack, Not(theStack[tos]))
elif op == "&":
    pop(None)
    pop(None)
    push(theStack, And(theStack[tos], theStack[tos + 1]))

您想先检索堆栈值 ,然后pop();或者调整tos偏移量以考虑它们已经减少,或以其他方式将pop()函数更改为返回弹出值。

目前,当您运行!(布尔 NOT )时,您从tos == 0移至tos == -1,然后将Not(theStack[-1])推回到堆。这不是你想要做的,因为theStack[-1]堆栈中最后一个元素,而不是现在活动堆栈的一部分。

然后在&的堆栈上执行tos == 2(布尔 AND )并弹出两次。现在您再次访问0并尝试解决theStack[0]theStack[1]问题。这里堆栈的偏移完全不正确;你刚刚从tos删除了两个,然后添加0和1,在堆栈的旧顶部下面找到两个值

我个人会使用pop()函数返回堆栈顶部并调整tos指针:

def pop(stack):
    global tos
    tos -= 1
    return stack[tos + 1]  # value at old position

然后使用它从堆栈中获取操作数:

elif op == "!":
    push(theStack, Not(pop(theStack)))
elif op == "&":
    push(theStack, And(pop(theStack), pop(theStack)))

答案 1 :(得分:0)

theStack = [len(expression)] 创建长度为len(expression)的列表 - 它会创建一个长度为1的列表,其中包含len(expression)中的值theStack[0] }。

要创建给定长度的列表,您可以执行

theStack = [0] * len(expression)]

这会将len(expression)的{​​{1}}元素初始化为零。