举个栗子:
str1=
"123ABCD456"
str2 =
"ABE12345D"
最长公共子串是:
123
最长公共子序列是:
12345
这两个都可以用动态规划,只是状态转移方程有点区别
最长公共子序列是:
dp[i][j] -- 表示子串str1[
0
...i]和子串str[
0
...j]的最长公共子序列
当str1[i] == str2[j]时,dp[i][j] = dp[i-
1
][j-
1
] +
1
;
否则,dp[i][j] = max(dp[i-
1
][j], dp[i][j-
1
]);
最优解为dp[len1-
1
][len2-
1
];
最长公共子串是: dp[i][j] -- 表示以str1[i]和str2[j]为结尾的最长公共子串 当str1[i] == str2[j]时,dp[i][j] = dp[i-
1
][j-
1
] +
1
; 否则,dp[i][j] =
0
;
最优解为max(dp[i][j]),其中
0
<=i<len1,
0
<=j<len2;
代码如下:
//求最长公共子串
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
String str1=scanner.next();
String str2=scanner.next();
System.out.println(getCommonStrLength(str1,str2));
}
scanner.close();
}
private static int getCommonStrLength(String str1, String str2) {
str1=" "+str1;
str2=" "+str2;
char[] a=str1.toCharArray();
char[] b=str2.toCharArray();
int m=a.length;
int n=b.length;
int[][]c=new int[m][n];
int max=0;
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (a[i]==b[j]) {
c[i][j]=c[i-1][j-1]+1;
}else {
c[i][j]=0;
}
if (max<c[i][j]) {
max=c[i][j];//记录最长子串
}
}
}
return max;
}
}
//求最长公共子序列
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
String str1=scanner.next();
String str2=scanner.next();
System.out.println(getCommonStrLength(str1,str2));
}
scanner.close();
}
private static int getCommonStrLength(String str1, String str2) {
str1=" "+str1;
str2=" "+str2;
char[] a=str1.toCharArray();
char[] b=str2.toCharArray();
int m=a.length;
int n=b.length;
int[][]c=new int[m][n];
int max=0;
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (a[i]==b[j]) {
c[i][j]=c[i-1][j-1]+1;
}else {
c[i][j]=Math.max(c[i-1][j], c[i][j-1]);
}
}
}
return c[m-1][n-1];
}
}