编程之美--3.3(2)最长公共子串
求两个字符串的最长公共子串。例如 strA="dabcabd" strB = "dbabcaeefbd" 最长公共子串为"abca"
方法:类似于编程之美3.3http://www.cnblogs.com/gnivor/articles/4604733.html
采用动态规划的方法。设定一个数组c[lenA+1][lenB+1],第0行和第0列均赋值为0。
动态转移方程为:
【1】如果strA.charAt(j - 1) == strB.charAt(i - 1),那么c[i][j]=c[i-1][j-1]+1
【2】如果strA.charAt(j - 1) != strB.charAt(i - 1),那么c[i][j]=0;
注意:c[i][j]第0行第0列不记录数组内的信息,且第0行和第0列实质上只用到了c[0][0]
然后在数组中找到最大的那个数,沿着对角线方向,向前一直推即可得到最长公共子串
public static String longestSameSubstring(String strA ,String strB) { int lenA = (int) strA.length(); int lenB = (int) strB.length(); int maxi = 0; int maxlen = 0; //c[i][j]存放的为子串相似的数量。(因为c的边界不算) int[][] c = new int[lenA + 1][lenB + 1]; // Record the distance of all begin points of each String // 初始化边界 for (int i = 0; i <= lenA; i++) c[i][0] = 0; for (int j = 0; j <= lenB; j++) c[0][j] = 0; c[0][0] = 0; //递推求出所有c元素 for (int i = 1; i <= lenA; i++) for (int j = 1; j <= lenB; j++) { if (strB.charAt(j - 1) == strA.charAt(i - 1)){ c[i][j] = c[i - 1][j - 1]+1; if(c[i][j]>maxlen){ maxi = i; maxlen=c[i][j]; } } else c[i][j] = 0; } for (int i = 0; i <= lenA; i++) { for (int j = 0; j <= lenB; j++) { System.out.print(c[i][j] + " "); } System.out.println(); } System.out.println("最大长度"+maxlen); int start = maxi-maxlen; return (String) strA.subSequence(start, maxi); }
main()
String str = longestSameSubstring("dabcabd","dbabcaeefbd");
System.out.println("最长公共子串为"+str);
结果:
0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 1
0 0 0 1 0 0 1 0 0 0 0 0
0 0 1 0 2 0 0 0 0 0 1 0
0 0 0 0 0 3 0 0 0 0 0 0
0 0 0 1 0 0 4 0 0 0 0 0
0 0 1 0 2 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 2
最大长度4
最长公共子串为abca

浙公网安备 33010602011771号