我想编写一个Python代码,它将使用堆栈计算表达式。我有以下代码,其中numStk
是一个包含数字的堆栈和保存运算符的optStk
。在表达式 2+3*4-6
中,在循环for
末尾,numStack
包含 2
、12
和 6
;optStk
包含-
和+
。现在如何使我的setOps()
函数从两个堆栈中弹出元素以执行表达式计算?
def main():
raw_expression = input("Enter an expression: ")
expression = raw_expression.replace(" ", "")
for i in expression:
if (i in numbers):
numStk.push(i)
else:
setOps(i)
optStk.push(i)
## code needed to evaluate the rest of the elements in stackstack
return valStk.top()
我的setOps(i)
函数如下:
def repeatOps(refOp):
while (len(valStk) > 1 and operators.index(refOp) <= operators.index(optStk.top())):
x = numStk.pop()
y = numStk.pop()
op = optStk.pop()
numStk.push(str(eval(x+op+y)))
即使我填写了您遗漏的所有内容,您的代码也存在问题:setOps()
似乎被称为repeatOps()
; numStk
有时被称为valStk
;您以错误的顺序进行评估,例如"6-5"被评估为"5-6";你在打电话给eval()
!
以下是我填写和修改您的代码以解决上述问题:
from collections import OrderedDict
DIGITS = "0123456789"
# position implies (PEMDAS) priority, low to high
OPERATORS = OrderedDict([
['+', lambda a, b: a + b],
['-', lambda a, b: a - b],
['*', lambda a, b: a * b],
['/', lambda a, b: a / b],
])
def operator_priority(character):
return list(OPERATORS.keys()).index(character)
class Stack(list):
""" minimalist stack implementation """
def push(self, thing):
self.append(thing)
def top(self):
return self[-1]
def evaluate(expression):
numStk = Stack()
optStk = Stack()
def setOps(refOp):
while numStk and optStk and operator_priority(refOp) <= operator_priority(optStk.top()):
y = numStk.pop()
x = numStk.pop()
op = optStk.pop()
print(x, op, y) # debugging
numStk.push(OPERATORS[op](x, y))
for i in expression:
if i in DIGITS:
numStk.push(int(i))
else:
setOps(i)
optStk.push(i)
if optStk:
# evaluate the rest of the elements in stacks
setOps(list(OPERATORS.keys())[0]) # trigger using lowest priority operator
return numStk.top()
if __name__ == "__main__":
raw_expression = input("Enter an expression: ")
expression = raw_expression.replace(" ", "")
print(evaluate(expression))
远非完美,但可以让你继续前进:
例
> python3 test.py
Enter an expression: 2+3*4-6
3 * 4
12 - 6
2 + 6
8
>
为了解决您最初的问题,完成评估的关键似乎是在optStk
中还剩任何东西时,使用虚构的低优先级运算符运行setOps()
。