繁体   English   中英

无法通过递归枚举所有算术表达式

[英]Cannot enumerate all arithmetic expressions by recursion

我想从给定的一组有序数字生成涉及+,-,*和/的所有可能表达式:

class Node:
    def __init__(self, data):
        self.left = None
        self.right = None
        self.data = data

    def is_leaf(self):
        if self.left is None:
            assert self.right is None
            return True
        return False

    def __repr__(self):
        if self.is_leaf():
            return repr(self.data)
        return '(%s%s%s)' % (self.left, self.data, self.right)


def enumerate_trees(numbers):
    n = len(numbers)
    if n == 1:
        yield Node(numbers[0])
    else:
        for i in range(1, n):
            left_subtrees = enumerate_trees(numbers[:i])
            right_subtrees = enumerate_trees(numbers[i:])
            for left in left_subtrees:
                for right in right_subtrees:
                    for op in ['+', '-', '*', '/']:
                        root = Node(op)
                        root.left = left
                        root.right = right
                        yield root


if __name__ == '__main__':
    for tree in enumerate_trees([5, 7, 10, 1]):
        print(repr(tree)[1:-1])

输出为:

5+(7+(10+1))
5-(7+(10+1))
5*(7+(10+1))
5/(7+(10+1))
5+(7-(10+1))
5-(7-(10+1))
5*(7-(10+1))
5/(7-(10+1))
5+(7*(10+1))
5-(7*(10+1))
5*(7*(10+1))
5/(7*(10+1))
5+(7/(10+1))
5-(7/(10+1))
5*(7/(10+1))
5/(7/(10+1))
5+(7+(10-1))
5-(7+(10-1))
5*(7+(10-1))
5/(7+(10-1))
5+(7-(10-1))
5-(7-(10-1))
5*(7-(10-1))
5/(7-(10-1))
5+(7*(10-1))
5-(7*(10-1))
5*(7*(10-1))
5/(7*(10-1))
5+(7/(10-1))
5-(7/(10-1))
5*(7/(10-1))
5/(7/(10-1))
5+(7+(10*1))
5-(7+(10*1))
5*(7+(10*1))
5/(7+(10*1))
5+(7-(10*1))
5-(7-(10*1))
5*(7-(10*1))
5/(7-(10*1))
5+(7*(10*1))
5-(7*(10*1))
5*(7*(10*1))
5/(7*(10*1))
5+(7/(10*1))
5-(7/(10*1))
5*(7/(10*1))
5/(7/(10*1))
5+(7+(10/1))
5-(7+(10/1))
5*(7+(10/1))
5/(7+(10/1))
5+(7-(10/1))
5-(7-(10/1))
5*(7-(10/1))
5/(7-(10/1))
5+(7*(10/1))
5-(7*(10/1))
5*(7*(10/1))
5/(7*(10/1))
5+(7/(10/1))
5-(7/(10/1))
5*(7/(10/1))
5/(7/(10/1))
5+((7+10)+1)
5-((7+10)+1)
5*((7+10)+1)
5/((7+10)+1)
5+((7+10)-1)
5-((7+10)-1)
5*((7+10)-1)
5/((7+10)-1)
5+((7+10)*1)
5-((7+10)*1)
5*((7+10)*1)
5/((7+10)*1)
5+((7+10)/1)
5-((7+10)/1)
5*((7+10)/1)
5/((7+10)/1)
(5+7)+(10+1)
(5+7)-(10+1)
(5+7)*(10+1)
(5+7)/(10+1)
(5+7)+(10-1)
(5+7)-(10-1)
(5+7)*(10-1)
(5+7)/(10-1)
(5+7)+(10*1)
(5+7)-(10*1)
(5+7)*(10*1)
(5+7)/(10*1)
(5+7)+(10/1)
(5+7)-(10/1)
(5+7)*(10/1)
(5+7)/(10/1)
(5+(7+10))+1
(5+(7+10))-1
(5+(7+10))*1
(5+(7+10))/1

从输出中至少可以看到两个问题:

  1. 某些树未到达,例如(((5 7) 10) 1)
  2. 对于某棵树,可能不是所有表达式都被覆盖。 例如对于树((5 (7 10)) 1) ,仅

     (5+(7+10))+1 (5+(7+10))-1 (5+(7+10))*1 (5+(7+10))/1 

    达到。

是什么原因? 谢谢。

您的递归调用如下所示:

left_subtrees = enumerate_trees(numbers[:i])
right_subtrees = enumerate_trees(numbers[i:])
for left in left_subtrees:
    for right in right_subtrees:
        #...

enumerate_trees返回一个生成器对象,该对象只能被迭代一次。 因此right_subtreesfor循环只会在第一次使用,而在外部for循环的下一次迭代中不会给出任何结果。

要解决此问题,您可以将递归调用直接放入for语句中,以便每次都执行它们,也可以使用list(enumerate_trees(...))将结果复制到列表中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM