You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求指导:将迭代实现的Newick树转二分划分函数改为递归实现

问题:Newick树转二分划分的递归实现思路求助

我知道作业类问题可能不受欢迎,但我确实卡壳了。我的任务是把Newick格式的树字符串转换成对应的二分划分,必须用递归方式实现。

示例

输入的Newick树:

tree = "((1,2),((3,((4,5),(6,7))),(8,9)))"
read_tree(tree)

对应的二分划分输出:

{{1},{2, 3, 4, 5, 6, 7, 8, 9}}
{{2},{1, 3, 4, 5, 6, 7, 8, 9}}
{{4},{1, 2, 3, 5, 6, 7, 8, 9}}
{{5},{1, 2, 3, 4, 6, 7, 8, 9}}
{{6},{1, 2, 3, 4, 5, 7, 8, 9}}
{{7},{1, 2, 3, 4, 5, 6, 8, 9}}
{{4, 5},{1, 2, 3, 6, 7, 8, 9}}
{{6, 7},{1, 2, 3, 4, 5, 8, 9}}
{{3},{1, 2, 4, 5, 6, 7, 8, 9}}
{{4, 5, 6, 7},{1, 2, 3, 8, 9}}
{{8},{1, 2, 3, 4, 5, 6, 7, 9}}
{{9},{1, 2, 3, 4, 5, 6, 7, 8}}
{{3, 4, 5, 6, 7},{8, 1, 2, 9}}
{{8, 9},{1, 2, 3, 4, 5, 6, 7}}
{{1, 2},{3, 4, 5, 6, 7, 8, 9}}
{{3, 4, 5, 6, 7, 8, 9},{1, 2}}

我的尝试

我试过很多思路都失败了,后来想到迭代可以转递归,先写了迭代实现的代码:

def read_tree(newick):
    leaf_set = set()
    index = 0
    for leaf in newick:
        if not leaf == "(" and not leaf == ")" and not leaf == ",":
            leaf_set.add(int(leaf))
    for e in newick:
        if e == ")":
            r_nodes = set()
            l_nodes = set()
            brace_counter = 0
            i_tmp = index-1
            add_ln = False
            add_nodes = True
            while add_nodes:
                if newick[i_tmp] == ")":
                    brace_counter += 1
                if newick[i_tmp] == "(":
                    brace_counter -= 1
                if newick[i_tmp] == "," and brace_counter == 0:
                    add_ln = True
                if not add_ln:
                    if not newick[i_tmp] == "(" 
                    and not newick[i_tmp] == ")" 
                    and not newick[i_tmp] == ",":
                        r_nodes.add(int(newick[i_tmp]))
                if add_ln:
                    if not newick[i_tmp] == "(" 
                    and not newick[i_tmp] == ")" 
                    and not newick[i_tmp] == ",":
                        l_nodes.add(int(newick[i_tmp]))
                if brace_counter == -1 and len(l_nodes) > 0:
                    add_nodes = False
                i_tmp -= 1
            print("{", end="")
            print(l_nodes, end=",")
            print(leaf_set.difference(l_nodes), end="}\n{")
            print(r_nodes, end=",")
            print(leaf_set.difference(r_nodes), end="}\n")
        index += 1

这个迭代版本应该能完成任务,但提交要求必须用递归,我又卡壳了,不知道怎么转成递归形式。不需要完整解决方案,只想要一些思路提示。谢谢!


递归实现思路提示

  • 抓住Newick的递归本质:每个括号包裹的子树都是独立的子问题,比如(A,B)可以拆成左子树A和右子树B,递归处理这两个子树后再合并结果。
  • 明确递归函数的返回值:让递归函数接收一段Newick子串,返回该子树包含的所有叶子节点集合,同时在递归过程中生成对应的二分划分(直接输出或收集起来)。
  • 处理终止条件:当子串是单个叶子节点(如"1"),直接返回该节点的集合,无需生成划分。
  • 正确拆分左右子树:对于非叶子子串,先去掉外层括号,然后找到括号计数为0时的逗号(即最外层的分隔逗号),将字符串拆分为左右两部分,分别递归处理。
  • 生成当前节点的二分划分:拿到左右子树的叶子集合后,用全量叶子集合计算补集,生成{左叶子集合, 补集}和{右叶子集合, 补集}(对应示例中的双向划分)。
  • 复用全量叶子集合:提前遍历整个Newick字符串收集所有叶子节点,作为参数传递给递归函数,方便快速计算补集。

内容的提问来源于stack exchange,提问作者Simon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 16:37:44