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

递归构建Binary Tree逻辑错误,是否应从中间连词开始构建?

问题描述

给定基础文本:

text = "The user's Average Revenue Per User (ARPU) has experienced a significant decrease due to high decrement and they have been inactive in terms of outgoing voice calls, data usage, and SMS for a consecutive period of 5 days. or they are having handset"

文本中的连词为:

conjunctions = [and, and, or]

需要构建指定的二叉树,并编写了基于spaCy的Python代码(代码如下),目前代码逻辑存在错误,询问是否应该选取中间连词作为起点,递归构建该二叉树?

import spacy


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


class Parser(object):
    def __init__(self, text=None):
        self.text = text
        pass

    def parse_left(self, conj_list, text):
        conj_index = cont_index_list[0][0]
        conj = str(conj_list[0][1])
        left = text.split(conj)[0]
        self.text = f"{conj}".join(self.text.split(conj)[1:])
        return left

    def parse_right(self, text, conj_list):
        # conj_index = cont_index_list[0][0]
        conj = str(conj_list[0][1])
        conj_next = None
        try:
            conj_next = str(conj_list[1][1])
        except:
            print("last conj")

        right = text.split(f" {conj} ")[0]
        self.text = f"{conj}".join(self.text.split(conj)[1:])
        # right = right.split(conj_next)
        return right

    def recursion_tree(self, node, text, conj_list):

        # code for if the text len is empty then return the tree

        # if ndoe is none create a leaf node
        if node is None:
            n1 = Node(conj_list[0][1])
            left = self.parse_left(conj_list, self.text)
            conj_list.pop(0)
            right = self.parse_right(self.text, conj_list)
            conj_list.pop(0)
            n1.left = left
            n1.right = right
            self.recursion_tree(n1, self.text, conj_list)
        else:
            n1 = Node(conj_list[0][1])
            n1.left = node
            right = self.parse_right(self.text, conj_list)
            n1.right = right
            self.recursion_tree(n1, self.text, conj_list)


if __name__ == '__main__':

    # Load the spaCy model
    nlp = spacy.load('en_core_web_sm')
    node = None
    text = "The user's Average Revenue Per User (ARPU) has experienced a significant decrease due to high decrement and they have been inactive in terms of outgoing voice calls, data usage, and SMS for a consecutive period of 5 days. or they are having handset"
    doc = nlp(text)
    # Extract conjunctions
    conjunctions = [token for token in doc if token.dep_ in {'cc', 'mark'} or token.pos_ == "CONJ"]
    conj_list = []
    cont_index_list = []

    for i in range(len(conjunctions)):
        print(i)
        conj_list.append((i, conjunctions[i]))
        cont_index_list.append((i, text.index(conjunctions[i].text)))
    p = Parser(text=text)
    p.recursion_tree(node, text, conj_list)
回答

是的,应该从中间连词(也就是第二个and)作为起点递归构建二叉树,核心原因是连词的语义优先级和文本的逻辑结构:

  • 最内层逻辑:outgoing voice calls, data usage, and SMS里的第二个and连接的是三个并列的通信行为,属于最细粒度的并列单元
  • 中间层逻辑:第一个and连接的是“ARPU大幅下降”和“连续5天无通信行为”两个并列的用户状态
  • 最外层逻辑:or连接的是“用户状态异常”和“终端问题”两个并列的原因分支

递归构建的正确逻辑应该是从最底层的连词开始,逐步向上合并:

  1. 以第二个and为根节点,左子节点为data usage,右子节点为SMS,将该子树替换原文本中data usage and SMS的部分,得到outgoing voice calls, [and子树]的片段
  2. 把outgoing voice calls和上述子树整合,作为“连续5天无通信行为”的具体内容
  3. 以第一个and为根节点,左子节点为“ARPU大幅下降”的文本,右子节点为第二步得到的子树
  4. 以最外层的or为根节点,左子节点为第三步的子树,右子节点为they are having handset

另外你当前代码的几个明显问题需要修正:

  • cont_index_list是全局变量,Parser类直接调用会报错,应改为实例属性传入或管理
  • 缺失递归终止条件,会引发无限递归
  • 直接用split分割文本会忽略上下文语义,应该结合spaCy的依存分析结果,定位每个连词真正连接的两个成分,而非简单切割字符串

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 08:47:51