您可以使用什么算法在字符串中查找重复的短语?

时间:2008-09-17 23:18:09

标签: algorithm language-agnostic parsing

给定一个任意字符串,找到重复短语的有效方法是什么?我们可以说短语必须超过一定的长度才能包括在内。

理想情况下,您最终会得到每个短语的出现次数。

5 个答案:

答案 0 :(得分:7)

理论上

  • suffix array 是“最佳”答案,因为它可以实现使用线性空间和时间来检测任何重复的子字符串。然而 - 天真的实现实际上需要花费时间O(n ^ 2 log n)来对后缀进行排序,并且如何将其减少到O(n log n)并不是完全明显的,更不用说O(n)了,尽管你可以阅读相关文章,如果你想。
  • suffix tree 可以占用更多的内存(但仍然是线性的),而不是后缀数组,但更容易实现快速构建,因为您可以使用类似基数排序的想法当您向树中添加内容时(有关详细信息,请参阅名称中的维基百科链接)。
  • KMP algorithm 也值得注意,它专门用于快速搜索较长字符串中的特定子字符串。如果您只需要这种特殊情况,只需使用KMP即可,无需首先构建足够的索引。

在实践中

我猜你正在分析一个实际自然语言(例如英语)单词的文档,而你实际上想要对你收集的数据做些什么。

在这种情况下,您可能只想对某些小n进行快速n-gram分析,例如只需n = 2或3.例如,您可以通过剥离将文档标记为单词列表标点符号,大小写和词干(运行,运行 - >'运行')以增加语义匹配。然后,只需构建每个相邻词对的哈希映射(例如C ++中的hash_map,python中的字典等)到目前为止的出现次数。最后,您将获得一些非常有用的数据,这些数据的编码速度非常快,并且运行速度不会太慢。

答案 1 :(得分:4)

像以前的人一样,提到后缀树是这项工作的最佳工具。我最喜欢的后缀树网站是http://www.allisons.org/ll/AlgDS/Tree/Suffix/。它列举了一个页面上后缀树的所有漂亮用法,并嵌入了测试js应用程序以测试字符串并通过示例进行操作。

答案 2 :(得分:1)

Suffix trees是实现这一目标的好方法。该文章的底部链接到不同语言的实现。

答案 3 :(得分:0)

就像jmah所说,你可以使用后缀树/后缀数组。

您可以使用here的算法进行描述(参见第3.1节)。

你可以在他们引用的书中找到更深入的描述(Gusfield,1997),on google books

答案 4 :(得分:0)

假设您有一个带有n个条目的排序数组A(i = 1,2,3,...,n)

Algo(A(i))
{
  while i<>n
  {
    temp=A[i];
    if A[i]<>A[i+1] then
    {     
      temp=A[i+1];
      i=i+1;
      Algo(A[i])
    }
    else if A[i]==A[i+1] then
      mark A[i] and A[i+1] as duplicates
  }
}

这个算法在O(n)时间运行。