如何在两个字符串中找到最大的COMMON子字符串?
答案 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 。然后有三种方法可以尝试找到最长的公共子序列:
这给了我们一个非常好的复发:
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的长度)。