import java.util.ArrayList;
import java.util.List;
/**
* 最长公共子串,注意不是最长公共子序列
* 子串是substr是原串连续的一部门, 子序列是可以不连续的
*
* @author liuyang
*
*/
public class MaxCommonSubstr {
public static void main(String[] args) {
char[] a = {'a','c','e','h','p'};
char[] b = {'b','e','h','k','p'};
//最长共公告子串的答案就是eh 如果是最长公共子序列,答案就是ehp
System.out.println("\n"+LC_Str2(a, b));
System.out.println();
System.out.println("\n"+LC_Str(a, b));
}
public static int LC_Str(char[] a,char[] b){
int max = 0;
int ea = -1;
int eb =-1;
int[][] c = new int[a.length+1][b.length+1];//之所以每一维多1,是留着边界条件用的,数组元素值默认就是0;
//c[i+1][j+1]表示以a[i] b[i]为结尾的最长公共子串的长度
for(int i = 0;i<a.length;i++){
for(int j=0;j<b.length;j++){
if(a[i]==b[j])
c[i+1][j+1]= 1+c[i][j];
if(c[i+1][j+1] > max){
max = c[i+1][j+1];
ea = i;
eb = j;
}
}
}
List result = new ArrayList();
for(int i = ea, j = eb;i>=0&&j>=0;i--,j--){
if(a[i]==b[j])
result.add(a[i]);
else
break;
}
for(int i = result.size()-1;i>=0;i--)
System.out.print(result.get(i)+" ");
return max;
}
public static int LC_Str2(char[] a,char[] b){
int max = 0;
int ea = -1;
int eb =-1;
int[][] c = new int[a.length+1][b.length+1];//之所以每一维多1,是留着边界条件用的,数组元素值默认就是0;
//c[i][j]表示以a[i] b[i]为开头的最长公共子串的长度
for(int i = a.length-1;i>=0;i--){
for(int j=b.length-1;j>=0;j--){
if(a[i]==b[j])
c[i][j]= 1+c[i+1][j+1];
if(c[i][j] > max){
max = c[i][j];
ea = i;
eb = j;
}
}
}
for(int i = ea, j = eb;i<a.length&&j<b.length;i++,j++){
if(a[i]==b[j])
System.out.print(a[i]+" ");
else
break;
}
return max;
}
}
本文介绍了一种求解最长公共子串问题的算法,并通过两个不同遍历方向的方法进行了实现。示例代码展示了如何找到两个字符数组之间的最长公共子串。
5206

被折叠的 条评论
为什么被折叠?



