X = <a, b, c, f, b, c>
Y = <a, b, f, c, a, b>
X和Y的Longest Common Substring为 <a, b>长度为2
动态规划解法
c[i][j]表示X0...Xi和Y0...Yj的最大SubstringXi=Yj)的长度,比如
X = <y, e, d, f>
Y = <y, e, k, f>
c[1][1] = 1
c[2][2] = 2
c[3][3] = 0
c[4][4] = 1
动态转移方程为:
如果xi == yj, 则 c[i][j] = c[i-1][j-1]+1
如果xi ! = yj, 那么c[i][j] = 0
最后求Longest Common Substring的长度等于
max{ c[i][j], 1<=i<=n, 1<=j<=m}
完整的代码如下:
- /**
- 找出两个字符串的最长公共连续子串的长度
- ** author :liuzhiwei
- ** data :2011-08-16
- **/
- #include "stdio.h"
- #include "string.h"
- #include "stdlib.h"
- int longest_common_substring(char *str1, char *str2)
- {
- int i,j,k,len1,len2,max,x,y;
- len1 = strlen(str1);
- len2 = strlen(str2);
- int **c = new int*[len1+1];
- for(i = 0; i < len1+1; i++)
- c[i] = new int[len2+1];
- for(i = 0; i < len1+1; i++)
- c[i][0]=0; //第0列都初始化为0
- for(j = 0; j < len2+1; j++)
- c[0][j]=0; //第0行都初始化为0
- max = -1;
- for(i = 1 ; i < len1+1 ; i++)
- {
- for(j = 1; j < len2+1; j++)
- {
- if(str1[i]==str2[j]) //只需要跟左上方的c[i-1][j-1]比较就可以了
- c[i][j]=c[i-1][j-1]+1;
- else
- c[i][j]=0;
- if(c[i][j]>max)
- {
- max=c[i][j];
- x=i;
- y=j;
- }
- }
- }
- //输出公共子串
- char s[1000];
- k=max;
- i=x-1,j=y-1;
- s[k--]='\0';
- while(i>=0 && j>=0)
- {
- if(str1[i]==str2[j])
- {
- s[k--]=str1[i];
- i--;
- j--;
- }
- else //只要有一个不相等,就说明相等的公共字符断了,不连续了
- break;
- }
- printf("最长公共子串为:");
- puts(s);
- for(i = 0; i < len1+1; i++) //释放动态申请的二维数组
- delete[] c[i];
- delete[] c;
- return max;
- }
- int main(void)
- {
- char str1[1000],str2[1000];
- printf("请输入第一个字符串:");
- gets(str1);
- printf("请输入第二个字符串:");
- gets(str2);
- int len = longest_common_substring(str1, str2);
- printf("最长公共连续子串的长度为:%d\n",len);
- system("pause");
- return 0;
- }