如何在两个字符串中找到最大的子字符串?

时间:2011-02-04 09:36:27

标签: string algorithm

如何在两个字符串中找到最大的COMMON子字符串?

3 个答案:

答案 0 :(得分:5)

可能使用Suffix Tree。为两个字符串创建树,然后使用这些结构查找常见的路径。

答案 1 :(得分:4)

我认为你可以使用在O(mn)时间和O(mn)空间中运行的非常优雅的动态编程算法来解决这个问题,其中m和n是每个字符串中的字符数。这个想法是基于以下重现。设两个字符串为A = a 0 a 1 a 2 ... a n-1 和B = b 0 b 1 b 2 ... b m-1 并查看他们的第一个字符a < sub> 0 和b 0 。然后有三种方法可以尝试找到最长的公共子序列:

  1. 如果第一个字符相等,则一个选项是找到两个字符串中其余字符串的最长公共子序列,然后将第一个字符添加到匹配项中。
  2. 或者,您可以决定不匹配前两个字符。在这种情况下,一个选项是查看在忽略第一个字符串的第一个字符时可以进行的最长公共子序列。 3最后,您还可以忽略第二个字符串的第一个字符。
  3. 这给了我们一个非常好的复发:

    LCS(A[0 .. n], B[0 .. m]) = longest of {
      A[0] + LCS(A[1 .. n], B[1 .. m])   (if A[0] == B[0]),
             LCS(A[1 .. n], B[0 .. m]),
             LCS(A[0 .. n], B[1 .. m])
        }
    

    作为我们的基本情况,任何字符串和空字符串的最长公共子字符串是空字符串:

    LCS (A[n .. n], B[i, m]) = ""
    LCS (A[i .. n], B[m, m]) = ""
    

    这个最长公共子串的定义允许您在给定三个值LCS(A [i + 1 .. n]的情况下计算LCS(A [i ... n],B [j ... m])的值,B [j + 1 ... m]),LCS(A [i ... n],B [j + 1 ... m])和LCS(A [i + 1 ... n],B [j。 .m])。因此,如果以正确的顺序计算这些值,则只需在一次通过中填充结果表并从中构造结果。使用一些标准的DP技巧,可以在O(mn)中运行。

答案 2 :(得分:0)

基本上有两种方式:1。动态编程,耗费O(mn)时间和O(mn)空间。 “templatetypedef”已经回答了这个问题。 2.后缀树,你需要先建立它,后缀链接的构建过程是O(m + n)(时间和空间),如果没有后缀链接是O((m + n)^ 2)(时间) )。虽然在最佳情况下构建后缀树进程与动态编程具有相同的效率,但是,在构建它之后,您可以在O(k)时间内获得最长的公共子字符串(k是LCS的长度)。