You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python:如何生成字典词汇集下句子的所有分词组合

解决全合法分词组合生成问题

嘿,我来帮你搞定这个全部分词组合生成的问题!你的需求是把句子ABCAB按照给定字典{'A': 3, 'B': 4, 'C': 5, 'AB':6}拆出所有可能的合法分词组合,但现有代码只返回一个结果,这问题我熟,咱们一步步来解决。

先说说原代码的问题

你原来的代码有几个关键问题导致只能返回一个结果:

  • 用了全局的words列表,递归过程中会被多次修改,不同分支的结果会互相干扰,最后只能保留一条路径。
  • 加了很多不必要的限制,比如word.startswith(sentence[0])会过滤掉后续位置的合法单词,word not in words更是完全错误——同一个单词本来就可以多次出现在分词结果里(比如示例里的AB)。
  • 函数逻辑混乱,比如find_words里调用了未定义的find_ngrams,流程走不通。

正确的解法:递归回溯

要生成所有可能的组合,递归回溯是最直接的思路——每一步尝试所有合法的单词,递归处理剩下的子串,处理完后回溯尝试其他可能,直到遍历完所有分支。

完整实现代码

# 定义你的词汇字典和最长单词长度
test_dict = {'A': 3, 'B': 4, 'C': 5, 'AB': 6}
max_word_length = max(len(word) for word in test_dict)

def generate_all_segmentations(sentence):
    # 用来存储所有合法的分词组合
    result = []
    
    def backtrack(remaining_str, current_path):
        # 如果剩余字符串为空,说明找到了一个完整的合法分词
        if not remaining_str:
            result.append(current_path.copy())
            return
        
        # 尝试所有可能的单词长度:从1到最长单词长度,或者剩余字符串的长度(取较小值)
        max_possible_len = min(max_word_length, len(remaining_str))
        for length in range(1, max_possible_len + 1):
            current_word = remaining_str[:length]
            # 如果当前子串在字典里,就继续递归
            if current_word in test_dict:
                current_path.append(current_word)
                # 递归处理剩下的字符串
                backtrack(remaining_str[length:], current_path)
                # 回溯:移除当前单词,尝试下一个可能的长度
                current_path.pop()
    
    # 启动回溯
    backtrack(sentence, [])
    return result

# 测试
sentence = "ABCAB"
all_results = generate_all_segmentations(sentence)
print(all_results)

运行结果

执行后会输出你想要的所有组合:

[['A', 'B', 'C', 'A', 'B'], ['A', 'B', 'C', 'AB'], ['AB', 'C', 'A', 'B'], ['AB', 'C', 'AB']]

代码解释

  • backtrack是核心递归函数:remaining_str是还没处理的剩余句子,current_path是当前已经选好的分词列表。
  • remaining_str为空时,说明我们已经把整个句子合法拆分完了,把当前路径的副本加入结果列表(用copy()是因为列表是可变对象,直接添加会导致后续修改影响已存入的结果)。
  • 遍历所有可能的单词长度,只要当前子串在字典里,就把它加入路径,递归处理剩下的部分;处理完后再把它从路径中移除(回溯),这样就能探索所有可能的分支。

这种方法逻辑清晰,能覆盖所有合法的分词组合,完全符合你的需求,而且不需要依赖itertools之类的库。

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

火山引擎 最新活动