我在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
之外的任何位置启动堆栈,实际上我只限于三种主要方法(LogicalEval
,push
,pop
)在LogicalEval
And
和Not
辅助方法之外的方法
答案 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}}元素初始化为零。