Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何迭代此树/图_Python_Tree - Fatal编程技术网

Python 如何迭代此树/图

Python 如何迭代此树/图,python,tree,Python,Tree,我需要迭代一个树/图并生成特定的输出,但遵循一些规则: _ d / / \ b c _e / / | a f g 预期输出应为(顺序无关): 这些规则是: 树的顶部“bde”(最左侧的_根_子项+根+最右侧的_根_子项)应始终存在 应保留左右顺序,例如不允许组合“cb”或“gf” 所有路径都遵循从左到右的方向 我需要找到所有遵循这些规则的路径。不幸的是,我没有CS背景,我的脑袋爆炸了。任何提示都会有帮助 编辑:此结构非常接近我的树: class N

我需要迭代一个树/图并生成特定的输出,但遵循一些规则:

     _ d
   /  / \
  b  c  _e
 /     / |
a     f  g
预期输出应为(顺序无关):

这些规则是:

  • 树的顶部“bde”(最左侧的_根_子项+根+最右侧的_根_子项)应始终存在
  • 应保留左右顺序,例如不允许组合“cb”或“gf”
  • 所有路径都遵循从左到右的方向
  • 我需要找到所有遵循这些规则的路径。不幸的是,我没有CS背景,我的脑袋爆炸了。任何提示都会有帮助

    编辑:此结构非常接近我的树:

    class N():
        """Node"""
        def __init__(self, name, lefts, rights):
            self.name = name
            self.lefts = lefts
            self.rights = rights
    
    tree = N('d', [N('b', [N('a', [], [])], []), N('c', [], [])], 
                  [N('e', [N('f', [], []), N('g', [], [])], 
                          [])])
    
    或者更易于阅读:

    N('d', lefts =[N('b', lefts=[N('a', [], [])], rights=[]), N('c', [], [])], 
           rights=[N('e', lefts=[N('f', [], []), N('g', [], [])], rights=[])])
    

    所以这可以看作是两个问题的结合。我下面的代码将假定
    N
    类和
    结构已在您的问题陈述中定义

    首先:给定像您这样的树结构,如何按顺序遍历其节点?这是一个非常简单的问题,所以我将展示一个简单的递归生成器来解决它:

    def inorder(node):
        if not isinstance(node, list):
            node = [node]
        for n in node:
            for left in inorder(getattr(n, 'lefts', [])):
                yield left
            yield n.name
            for right in inorder(getattr(n, 'rights', [])):
                yield right
    
    print list(inorder(tree))
    # ['a', 'b', 'c', 'd', 'f', 'g', 'e']
    
    Second:现在我们已经有了节点的“正确”顺序,接下来我们需要找出所有可能的组合,这些组合a)保持这个顺序,b)包含三个“锚”元素(
    'b','d','e'
    )。这一点,我们可以通过使用总是方便的库中的一些帮助来实现

    基本步骤是:

    • 确定锚元素,并将列表划分为四个部分
    • 计算每个分区(即电源组)的所有元素组合
    • 以所有这些组合的乘积为例
    像这样:

    from itertools import chain, combinations
    # powerset recipe taken from itertools documentation
    def powerset(iterable):
        "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
        s = list(iterable)
        return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
    
    def traversals(tree):
        left, mid, right = tree.lefts[0].name, tree.name, tree.rights[0].name
        nodes = list(inorder(tree))
        l_i, m_i, r_i = [nodes.index(x) for x in (left, mid, right)]
        parts = nodes[:l_i], nodes[l_i+1:m_i], nodes[m_i+1:r_i], nodes[r_i+1:]
        psets = [powerset(x) for x in parts]
        for p1, p2, p3, p4 in product(*psets):
            yield ''.join(chain(p1, left, p2, mid, p3, right, p4))
    
    print list(traversals(tree))
    # ['bde', 'bdfe', 'bdge', 'bdfge', 'bcde', 'bcdfe', 
    #  'bcdge', 'bcdfge', 'abde', 'abdfe', 'abdge', 'abdfge', 
    #  'abcde', 'abcdfe', 'abcdge', 'abcdfge']
    

    展示你的尝试!老实说,我不知道如何开始。我在考虑一个双for循环,但我觉得我需要做一些递归。我不能把所有的东西都放在一起。d和f/g或b和c之间没有直接的路线。很难发现预期输出背后的逻辑(为什么和什么时候从d跳到g,然后跳到f,再跳回到e)。这棵树是什么格式的?你说这是一棵二叉树,但d似乎有3个子树?这个例子是一个错误,还是不是二进制的?答案很好!现在我知道我离自己做这件事还有多远了。谢谢
    from itertools import chain, combinations
    # powerset recipe taken from itertools documentation
    def powerset(iterable):
        "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
        s = list(iterable)
        return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
    
    def traversals(tree):
        left, mid, right = tree.lefts[0].name, tree.name, tree.rights[0].name
        nodes = list(inorder(tree))
        l_i, m_i, r_i = [nodes.index(x) for x in (left, mid, right)]
        parts = nodes[:l_i], nodes[l_i+1:m_i], nodes[m_i+1:r_i], nodes[r_i+1:]
        psets = [powerset(x) for x in parts]
        for p1, p2, p3, p4 in product(*psets):
            yield ''.join(chain(p1, left, p2, mid, p3, right, p4))
    
    print list(traversals(tree))
    # ['bde', 'bdfe', 'bdge', 'bdfge', 'bcde', 'bcdfe', 
    #  'bcdge', 'bcdfge', 'abde', 'abdfe', 'abdge', 'abdfge', 
    #  'abcde', 'abcdfe', 'abcdge', 'abcdfge']