我正在尝试找到一种有效的算法来识别重复出现的字符序列。假设序列可以是至少3个字符,但只返回最大长度序列。数据集可能有数千个字符。另外,我只想知道序列是否重复,比方说,3次。
举个例子: ASHEKBSHEKCSHEDSHEK
“SHEK”发生3次并将被识别。 “SHE”出现4次,但未被识别,因为“SHEK”是包含该序列的最大长度序列。
此外,没有“种子”序列被送入算法,它必须自动找到它们。
提前致谢, Ĵ
答案 0 :(得分:2)
答案 1 :(得分:0)
看起来像Rabin-Karp Wiki Entry
答案 2 :(得分:0)
如果你认为存在\ sum(n)/ 2个可能的起始字符串,并且你不是在寻找 a 匹配,而是匹配最多的子字符串,我想如果要正确和完整,你的算法将具有可怕的理论复杂性。
但是,使用Trie可能会获得一些实际的速度。算法会是这样的:
一旦你建立了trie来建模数据,删除trie中的所有子树,其根低于某个优化阈值(在你的情况下为3)。
剩下的路径应该足够少,以便您有效地排序和挑选您想要的路径。
我建议将此作为起点,因为Trie是为了操纵公共前缀而构建的,并且作为副作用会压缩您的数据集。
我要做的个人选择是在识别出我想要的子串后,将子串的位置识别为一个单独的过程。否则你将存储每个子字符串位置,这将爆炸你的记忆。你的计算已经非常复杂了。
希望这有一定道理!祝你好运!
答案 3 :(得分:0)
考虑以下算法,其中:
str
是一系列事件
T(i)
是子字符串str(0..i)
的{{3}}。
T(i+1)
可以从T(i)
快速获取,例如使用suffix tree
对于输入字符串i
中的每个字符位置str
,遍历a
路径从T(i)
的根开始,沿着边缘标记为
输入中的连续字符,从位置i + 1
开始。
此路径确定重复字符串。如果路径长于
先前找到的路径,记录新的最大长度和位置
i + 1
。
使用str [i+1]
更新后缀树,然后重复下一个位置。
像这样的伪代码:
max.len = 0
max.off = -1
T = update_suffix_tree (nil, str [0])
for i = 1 to len (str)
r = root (T)
j = i + 1
while j < len (str) and r.child (str [j]) != nil
r = r.child (str [j])
++j
if j - i - 1 > max.len
max.len = j - i - 1
max.off = i + 1
T = update_suffix_tree (T, str [i+1])
在k
次迭代中,内部while
执行最多n -
k
次迭代,后缀树结构为O(k)
,因此
循环体的复杂度为O(n)
,并且执行n-1
次,
因此整个算法的复杂度为O(n^2)
。