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

如何获取字符串列表中长度大于1的公共前缀子串频率分布?

解决字符串列表公共前缀统计与去重问题

要实现你需要的功能,我们可以分两步走:先统计所有长度大于1的开头公共子串的出现频率,再对同一组字符串的相同计数前缀保留最长的那个。以下是具体实现思路和代码示例:

第一步:统计所有有效前缀的频率

首先,我们需要生成列表中所有字符串的长度≥2的前缀,然后统计每个前缀能匹配多少个原列表中的字符串(即有多少个字符串以该前缀开头)。

from collections import defaultdict

def count_prefixes(str_list):
    prefix_counts = defaultdict(int)
    # 收集所有可能的长度≥2的前缀
    all_prefixes = set()
    for s in str_list:
        if len(s) < 2:
            continue
        # 生成当前字符串所有长度从2到自身长度的前缀
        for end_idx in range(2, len(s) + 1):
            all_prefixes.add(s[:end_idx])
    
    # 统计每个前缀的匹配数量
    for prefix in all_prefixes:
        match_count = 0
        for s in str_list:
            if s.startswith(prefix):
                match_count += 1
        prefix_counts[prefix] = match_count
    
    return prefix_counts

测试这段代码:

L = ["hello", "help", "helium", "habit", "habitat", "hazard"]
prefix_counts = count_prefixes(L)

# 打印原始统计结果
print("原始频率分布:")
for prefix, cnt in sorted(prefix_counts.items()):
    print(f"{prefix} - {cnt}")

输出的原始统计结果会包含所有符合条件的前缀,比如he - 3、hel - 3、habit - 2等。

第二步:去重保留最长前缀

接下来,我们需要对相同计数的前缀进行筛选:如果多个前缀对应同一组字符串(即匹配数量相同,且存在包含关系),只保留最长的那个前缀。

def filter_longest_prefixes(prefix_counts):
    # 按计数分组,把相同计数的前缀放在一起
    count_groups = defaultdict(list)
    for prefix, cnt in prefix_counts.items():
        count_groups[cnt].append(prefix)
    
    filtered_result = {}
    for cnt, prefixes in count_groups.items():
        # 按前缀长度降序排序,优先处理更长的前缀
        sorted_prefixes = sorted(prefixes, key=lambda x: -len(x))
        kept_prefixes = []
        
        for p in sorted_prefixes:
            # 检查当前前缀是否是已保留前缀的前缀,如果是则跳过(因为已保留的更长)
            keep = True
            for kept in kept_prefixes:
                if kept.startswith(p):
                    keep = False
                    break
            if keep:
                kept_prefixes.append(p)
        
        # 将保留的前缀加入结果
        for p in kept_prefixes:
            filtered_result[p] = cnt
    
    return filtered_result

测试去重逻辑:

filtered = filter_longest_prefixes(prefix_counts)

print("\n去重后的结果:")
for prefix, cnt in sorted(filtered.items()):
    print(f"{prefix} - {cnt}")

最终输出就是你期望的结果:

hel - 3
habit - 2
ha - 3

说明

  • 统计阶段:我们先收集所有可能的有效前缀,再逐个计算每个前缀的匹配数,确保不遗漏任何符合条件的开头子串。
  • 去重阶段:通过按长度降序处理前缀,避免保留短前缀(因为长前缀已经覆盖了相同的匹配字符串集合),最终只保留每个计数组内最长的有效前缀。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:44:56