最长公共子串

来源:互联网 发布:linux识别中文字体 编辑:程序博客网 时间:2024/06/14 01:53

找 两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。其实这又是一个序贯决策问题,可以用动态规划来求解。我们采用一个二维矩阵来记录中间的结 果。这个二维矩阵怎么构造呢?直接举个例子吧:"bab"和"caba"(当然我们现在一眼就可以看出来最长公共子串是"ba"或"ab")

   b  a  b

c  0  0  0

a  0  1  0

b  1  0  1

a  0  1  0

我们看矩阵的斜对角线最长的那个就能找出最长公共子串。

不过在二维矩阵上找最长的由1组成的斜对角线也是件麻烦费时的事,下面改进:当要在矩阵是填1时让它等于其左上角元素加1

   b  a  b

c  0  0  0

a  0  1  0

b  1  0  2

a  0  2  0

这样矩阵中的最大元素就是 最长公共子串的长度。

将二维数组c[i][j]用来记录具有这样特点的子串——结尾同时也为为串x 1 x 2 x i  x1x2⋯xiy 1 y 2 y j  y1y2⋯yj的结尾——的长度。

得到转移方程:

        /    0                         if i<0 or j<0

c[i,j]=        c[i-1,j-1]+1                 if i,j>=0 and xi=xj

        \    0         if i,j>=0 and xi≠xj

最长公共子串的长度为 max(c[i,j]), i{1,,m},j{1,,n} max(c[i,j]), i∈{1,⋯,m},j∈{1,⋯,n}

public static int lcs(String str1, String str2) {    int len1 = str1.length();    int len2 = str2.length();    int result = 0;     //记录最长公共子串长度    int c[][] = new int[len1+1][len2+1];    for (int i = 0; i <= len1; i++) {        for( int j = 0; j <= len2; j++) {            if(i == 0 || j == 0) {                c[i][j] = 0;            } else if (str1.charAt(i-1) == str2.charAt(j-1)) {                c[i][j] = c[i-1][j-1] + 1;                result = max(c[i][j], result);            } else {                c[i][j] = 0;            }        }    }    return result;}


0 0
原创粉丝点击