一、问题描述
求两个字符串的最长公共子串,经典的动态规划问题。算法导论中有详细的讲解。
二、解题思路
如若两个字符串分别为:X=abcfbc和Y=abfcab。创建一个二维数组c[][],维数分别是两个字符串的长度加一。定义c[i][j]表示Xi和Yj的最长公共子串(LCS).当i或j等于0时,c[i][j]=0. LCS问题的最优子结构存在以下递归式:
c[i][j] = 0 i=0 or j=0
c[i][j] = c[i-1][j-1] Xi == Yj
c[i][j] = max(c[i][j-1], c[i-1][j]) Xi != Yj
从最后一个单元格向上顺着箭头的方向可以找到最长子串的构成,在由箭头组成的线段中,含有斜向上的箭头是LCS对应的其中的一个字符。
三、代码实现
#include<stdio.h>
#include<string.h>
void LCS(char x[],char y[],int c[][500],int m,int n)
{
int i,j;
for(i=0;i<m;i++)
{
c[i][0]=0;
}
for(i=1;i<n;i++)
{
c[0][i]=0;
}
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
if(x[i-1]==y[j-1]) c[i][j]=c[i-1][j-1]+1;
else if(c[i-1][j]>=c[i][j-1]) c[i][j]=c[i-1][j];
else c[i][j]=c[i][j-1];
}
}
}
int main()
{
int m,n;
char x[500],y[500];
int c[500][500];
while(scanf("%s%s",x,y)!=EOF)
{
m=strlen(x);
n=strlen(y);
LCS(x,y,c,m,n);
printf("%d\n",c[m][n]);
}
return 0;
}