最长公共子串:两个字符串中的最常公共连续子串。
找 两个字符串的最长公共子串,这个子串要求在原字符串中是连续的。其实这又是一个序贯决策问题,可以用动态规划来求解。我们采用一个二维矩阵来记录中间的结 果。这个二维矩阵怎么构造呢?直接举个例子吧:"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
这样矩阵中的最大元素就是 最长公共子串的长度。
import java.util.Scanner;
public class Main {
public static void main (String args[]){
Scanner in=new Scanner(System.in);
while(in.hasNextLine()){
String a=in.nextLine();//读取当前行
String b=in.nextLine();
System.out.print(getLCS(a,b));
}
in.close();
}
public static String getLCS(String a, String b) {
if (a == null || b == null || a.length() == 0 || b.length() == 0) {
return null;
}
int[][] dp = new int[a.length()][b.length()];
int endHere = 0;
int maxLen = 0;
for (int i = 0; i < a.length(); i++) {
for (int j = 0; j < b.length(); j++) {
if (i == 0 || j == 0) {
dp[i][j] = a.charAt(i) == b.charAt(j) ? 1 : 0;
} else {
dp[i][j] = a.charAt(i) == b.charAt(j) ? dp[i - 1][j - 1] + 1: 0;
}
if (dp[i][j] > maxLen) {
maxLen = dp[i][j];
endHere = i;
}
}
}
return a.substring(endHere - maxLen + 1, endHere + 1);
}
}