在 Python 中为中缀表示法添加前缀表示法
Posted
技术标签:
【中文标题】在 Python 中为中缀表示法添加前缀表示法【英文标题】:Prefix notation to infix notation in Python 【发布时间】:2011-09-23 19:24:41 【问题描述】:我正在编写一个小型计算器(带有前缀符号),我很好奇如何将前缀符号转换为中缀符号。我目前有一个功能,但它很奇怪,我不知道如何修复它。奇怪的是,我的意思是如果给定['+', x, y]
,它将返回(() + x + () + y)
,这让我很困惑。这是代码。
def pre_in(read):
#print read
tempOp = read[0]
body = read[1:]
expr = []
for i in range(len(body)-1):
if not isinstance(body[i], list) and body[i] != " ":
expr.append(str(body[i]))
expr.append(tempOp)
else:
expr.append(str(pre_in(body[i])))
expr.append(tempOp)
try:
if not isinstance(body[-1], list):
expr.append(str(body[-1]))
else:
expr.append(str(pre_in(body[-1])))
except:
pass
if expr != None: return "("+' '.join(expr)+")"
我做错了什么?
【问题讨论】:
我不明白这个问题(和你的代码)。如果我有foo = ['+', x, y]
,表达式[foo[1], foo[0], foo[2]]
将导致[x, '+', y]
。这不是你想要的吗?在嵌套表达式的情况下,您必须进行简单的递归。也许您应该给出一个更清晰、更复杂的输入和预期输出示例。
你也可以尝试使用堆栈,这是做前缀的常用方法中缀,堆栈也可以解决嵌套表达式。
似乎与同一个人的上一个问题有关:***.com/questions/6338440/small-language-in-python
Space_C0wb0y:我的目标是可以处理多个术语,例如 ['+', 2, 3, 4, 5]
会产生 2 + 3 + 4 + 5
@Warren 实际上没有。这是关于前缀的,另一个是关于后缀的。我正在重新考虑语言的结构
【参考方案1】:
对于这种简单的解析/转换作业可能有点矫枉过正,您可能需要查看pyparsing。
【讨论】:
【参考方案2】:这是一个相当简单的递归解决方案。
def prefix_to_infix(expr):
if type(expr) != type([]):
# The expression is a number or variable.
return str(expr)
elif len(expr) == 2:
# This is an operator expression with 1 argument.
return str(expr[1])
else:
# This is an operator expression with 2 or more arguments.
operator = expr[0]
left_arg = prefix_to_infix([operator] + expr[1:-1])
right_arg = prefix_to_infix(expr[-1])
return "(012)".format(left_arg, operator, right_arg)
# prefix_to_infix(['+',1,2,3,4,5]) = '((((1+2)+3)+4)+5)'
# prefix_to_infix(['+',1,2,['*',3,4,5],6,7,8]) = '(((((1+2)+(3*4*5))+6)+7)+8)'
【讨论】:
但是有三角函数之类的? 我在假设您的前缀表达式的语法是 ['operator', arg1, arg2, ... ,argN] 的形式下工作。我还假设所有运算符都是二元运算符并且是左关联的。用中缀表示法制作三角函数真的没有意义,但也许我只是误解了你的问题。【参考方案3】:实际上你的代码运行良好。
print pre_in ( ['+', 8, 9] )
产量
(8 + 9)
编辑: 正如其他人所说,也许您想使用堆栈。这是一个简单的沙盒实现,带有一些示例(它产生了很多括号,但这些并没有坏处):
class Calculator:
def __init__ (self):
self.stack = []
def push (self, p):
if p in ['+', '-', '*', '/']:
op1 = self.stack.pop ()
op2 = self.stack.pop ()
self.stack.append ('(%s %s %s)' % (op1, p, op2) )
elif p == '!':
op = self.stack.pop ()
self.stack.append ('%s!' % (op) )
elif p in ['sin', 'cos', 'tan']:
op = self.stack.pop ()
self.stack.append ('%s(%s)' % (p, op) )
else:
self.stack.append (p)
def convert (self, l):
l.reverse ()
for e in l:
self.push (e)
return self.stack.pop ()
c = Calculator ()
print c.convert ( ['+', 8, 9] )
print c.convert ( ['!', 42] )
print c.convert ( ['sin', 'pi'] )
print c.convert ( ['+', 'sin', '/', 'x', 2, 'cos', '/', 'x', 3] )
【讨论】:
我通常在带有变量的表达式上运行它,例如:['+', x, y]x = 8; y = 9; print pre_in ( ['+', x, y] )
也运行良好。
我的意思是 ['+', 'x', 'y']
对不起,我输入错误。
/ x + y z
和 / + y z x
不是等效的吗?【参考方案4】:
如果您的目标不是自己开发算法,请转至this page。有两个页面的链接解释了中缀->后缀和后缀->中缀算法。 (另外,如果你想知道算法是如何在 javascript 中实现的,你可以看看页面的源代码。)
【讨论】:
以上是关于在 Python 中为中缀表示法添加前缀表示法的主要内容,如果未能解决你的问题,请参考以下文章