Python 中缀符号、堆栈和队列
我正在为我的大学课堂做一个作业,我们需要写一个脚本来计算由括号(即“((4/3)*2)*5)”绑定的一系列数学表达式。我们还需要使用堆栈和队列来完成教授提供给我们的作业。我让我的代码工作,但它没有给我正确的输出。任何关于我做错了什么的见解都是有帮助的 以下是我用Python 3编写的代码:Python 中缀符号、堆栈和队列,python,python-3.x,Python,Python 3.x,我正在为我的大学课堂做一个作业,我们需要写一个脚本来计算由括号(即“((4/3)*2)*5)”绑定的一系列数学表达式。我们还需要使用堆栈和队列来完成教授提供给我们的作业。我让我的代码工作,但它没有给我正确的输出。任何关于我做错了什么的见解都是有帮助的 以下是我用Python 3编写的代码: import isfloat import Queue import Stack def expr_eveluate(expr_string): """ :Pre: Given a math
import isfloat
import Queue
import Stack
def expr_eveluate(expr_string):
"""
:Pre: Given a mathematical expression, this function
evaluates it per pairs of brackets.
:Post: The expression must be evaluated per pairs of brackets
:param expr_string: A string of mathematical expressions
:return:
"""
# A queue for data to be processed.
waiting_line = Queue.create()
# A stack where processed operators go.
operator_stack = Stack.create()
# A stack where processed numbers go.
numerical_value = Stack.create()
# Put all the items in Queue
expr = expr_string.split()
for item in expr:
Queue.enqueue(waiting_line, item)
while not Queue.is_empty(waiting_line):
item = Queue.dequeue(waiting_line)
if item == '(':
pass
elif isfloat.isfloat(item):
Stack.push(numerical_value, item)
elif not isfloat.isfloat(item):
Stack.push(operator_stack, item)
else:
num1 = Stack.pop(numerical_value)
num2 = Stack.pop(numerical_value)
op = Stack.pop(operator_stack)
if op == '*':
val = num1 * num2
Stack.push(numerical_value, val)
if op == '/':
val = num1 / num2
Stack.push(numerical_value, val)
if op == '+':
val = num1 + num2
Stack.push(numerical_value, val)
if op == '-':
val = num1 - num2
Stack.push(numerical_value, val)
else:
print("Syntax Error")
return None
return Stack.pop(numerical_value)
我发现你的代码有几个问题。这是一份简况
float(item)
推到numeric\u堆栈
,而不是在isfloat.isfloat(item)
案例中只推item
if
/elif
/else
链中的条件彼此不一致。如果你改变周围块的顺序,你也许可以保留一些相同的逻辑,但是我认为如果你改善条件,当前的顺序是好的
特别是在elif not isfloat.isfloat(item):
行中,条件将始终为true(因为您已经处理了前面elif
块中的数字)。这意味着右括号将被推到操作符堆栈上,else
块将永远不会运行。我认为您应该在这里使用类似于“*”、“/”、“+”、“-”:中的elif项来显式测试期望的运算符
类似地,顶层的else
块可能应该是elif item==”
,明确测试它希望处理的令牌
else
块中的if
s可能是一系列if
和elif
s,因为您一次只希望运行其中一个。当前,末尾的else
子句将针对任何非-
运算符运行,而不是针对未知运算符值运行
说到内部的else
块,它应该没有一个级别的影响,因此它是外部if
/elif
链的一部分,而不是内部操作符处理链。您需要在顶层检查无效令牌,因为操作符\u堆栈
希望不会再被推到它上面数字堆栈中弹出两个数字时,您处理它们的顺序是错误的。堆栈顶部的第一个数字始终是运算符右侧的值,而弹出的第二个数字将是左侧的值。目前您将3/4
解释为4/3
。这很容易解决,只需在执行pop
调用的行中交换num1
和num2
。你甚至可能想重新命名这些变量,比如“代码>右< /COD>”和“代码>左< /C> >,以使操作更加清楚。
”(((4/3)*2)*5)
上运行代码,由于括号紧密,因此无法正确处理代码。您需要将其传递给”((4/3)*2)*5)
,这样您正在使用的split
调用将正确地分离所有令牌。我会检查你作业的细节,看看你是否需要编写一个更复杂的标记器,或者你是否可以对测试使用的输入更加小心isfloat是我们教授提供的另一个模块。尝试将字符转换为浮点。我对你的标题有点困惑。反向波兰语表示法在参数后有运算符(例如
12+
),但你问的是带括号的普通表示法(例如(1+2)
)。哦,对不起,我不熟悉表示法本身,但我的朋友说它是RPN或后缀表示法。