在 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 中为中缀表示法添加前缀表示法的主要内容,如果未能解决你的问题,请参考以下文章

可以仅使用队列将中缀表示法的字符串转换为前缀表示法吗? (考虑唯一的操作是 + 和 - 的情况)

书写表达式:中缀、后缀和前缀

前缀表达式中缀表达式和后缀表达式

算术表达式的前缀,中缀,后缀相互转换

通用编程语言如何解析中缀表达式?

前缀中缀后缀表达式