求一个字符串是否是另一个字符串的子串我们可以用KMP算法,但是如何求两个字符串的最长公共子串?,穷举法肯定可以求出来,但是穷举的子串有(n+1)Xn/2+(m+1)Xm/2个,再一一比较,比较的次数是(1+2^2+3^2…n^2)次,这样一来所消耗的时间太多了,如果比较两个长度都是100的字符串,机器都要运行很长时间,况且代码也不好写,所以我们采用动态规划的思想来解决这个问题。
如果其中一个字符串m的前(n-1)个字符是另一个字符串s的子串,那么我们只需要比较m的第n个字符是不是与s的已经匹配的字符串的下一个字符相等,如果相等那么匹配成功,如果不相等那么最长公共子串是n-1个字符构成的字符串。
现在只要确定最长字串的起始位置就可以找到最长公共子串。那么如何确定最长的子串是从第几位字符开始的?我们可以从第一个字符开始,一个个找,直到找到最后一个字符,然后一比较就可以确定最长子串的起始位置。
下面是主要代码,其余代码请自行补全
//从b的第一个字符开始找
for(i = 0;i<b.length;i++){
k = i;
//依次匹配,如果匹配成功就记录在矩阵a中
for(j = 0;j<c.length&&k<b.length;j++){
if(b[k]==c[j]){
a[i][j] = 1;
k = k+1;
}else{
k = i;
}
}
}
//len记录公共子串的最长长度,begin是匹配最长公共子串的起始位置,end是终止位置
int len = 0,h=0,begin = 0,end = 0;
for(i = 0;i<b.length;i++){
//sum是临时变量,存储以第i个字符开始的最长公共子串的长度
//l是起始位置,m是终止位置
int sum = 0;
int l = 0;
int m = 0;
for(j = 0;j<c.length;j++){
//已经匹配成功的都记录在矩阵a中,现在只需要找最长的子串
if(a[i][j]==1){
m++;
sum++;
//如果找到长度更长的子串就记录下来
if(sum>len){
len = sum;
h = i;
if(a[i][l]==0){
begin = l+1;
}else{
begin = l;
}
end = m;
}
}else{
l = j;
m = j;
sum = 0;
}
}
}
运行结果: