如何找到重复的事件序列

时间:2011-11-10 14:39:58

标签: java algorithm

我正在尝试找到一种有效的算法来识别重复出现的字符序列。假设序列可以是至少3个字符,但只返回最大长度序列。数据集可能有数千个字符。另外,我只想知道序列是否重复,比方说,3次。

举个例子: ASHEKBSHEKCSHEDSHEK

“SHEK”发生3次并将被识别。 “SHE”出现4次,但未被识别,因为“SHEK”是包含该序列的最大长度序列。

此外,没有“种子”序列被送入算法,它必须自动找到它们。

提前致谢, Ĵ

4 个答案:

答案 0 :(得分:2)

尝试为字符串创建后缀数组。

在线构建器:http://allisons.org/ll/AlgDS/Strings/Suffix/

检查后缀数组中连续行的开头以匹配

答案 1 :(得分:0)

看起来像Rabin-Karp Wiki Entry

答案 2 :(得分:0)

如果你认为存在\ sum(n)/ 2个可能的起始字符串,并且你不是在寻找 a 匹配,而是匹配最多的子字符串,我想如果要正确和完整,你的算法将具有可怕的理论复杂性。

但是,使用Trie可能会获得一些实际的速度。算法会是这样的:

  1. 对于字符串中的每个偏移量... 1对于每个长度子串...
    1. 将其插入特里。 trie中的每个节点都有一个数据值(" count"整数),当你访问节点时,它会递增。
  2. 一旦你建立了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)