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

如何判断列表中哪些字符串是经旋转得到的等价字符串?

找出字符串列表中的旋转等价组

核心思路

判断两个字符串是否仅存在旋转差异,最精准且高效的方式是:

  1. 首先确认两个字符串长度相同(长度不同不可能是旋转关系);
  2. 检查其中一个字符串是否是另一个字符串与自身拼接后的子串(比如s2 in s1 + s1)。

为了批量分组,我们可以给每个旋转等价组生成一个唯一标识:取该字符串所有旋转形式中字典序最小的那个作为键,这样同组的字符串会对应同一个键,以此实现快速分组。

实现代码

1. 生成旋转等价标识的函数

def get_rotation_key(s):
    if not s:
        return ""
    # 生成当前字符串的所有旋转形式,取字典序最小的作为分组键
    rotations = [s[i:] + s[:i] for i in range(len(s))]
    return min(rotations)

如果处理超长字符串,可改用更高效的Booth算法(无需生成所有旋转),但上述方法对大部分场景已足够简洁实用。

2. 批量分组处理

from collections import defaultdict

# 目标字符串列表
str_list = ['1010', '122a916b2a916b7667110161', '20000000', '2020', '2a916b', '2a916b7667110161122a916b', '6b7667110161122a916b2a91', '916b7667110161122a916b2a', 'ffff']

# 按旋转等价性分组
groups = defaultdict(list)
for s in str_list:
    key = get_rotation_key(s)
    groups[key].append(s)

# 输出结果
for idx, (_, members) in enumerate(groups.values(), 1):
    print(f"等价组 {idx}:{members}")

为什么比difflib/Levenshtein更优

  • difflib.SequenceMatcher和Levenshtein.ratio是计算字符串相似度的工具,仅能判断两个字符串是否完全相同(相似度为1),但无法区分“完全相同”和“旋转等价”,且需要两两比较所有字符串,时间复杂度为O(n²),效率较低;
  • 旋转标识分组法仅需遍历一次字符串列表,时间复杂度为O(n*L)(n为字符串数量,L为单字符串长度),既能精准识别旋转等价组,又能大幅提升处理效率。

示例输出结果

运行上述代码后,会得到以下分组:

  • 等价组 1:['1010']
  • 等价组 2:['122a916b2a916b7667110161', '2a916b7667110161122a916b', '6b7667110161122a916b2a91', '916b7667110161122a916b2a']
  • 等价组 3:['20000000']
  • 等价组 4:['2020']
  • 等价组 5:['2a916b']
  • 等价组 6:['ffff']

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 13:48:40