问题描述:
最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已知序列的最长公共子序列。
例如:X(A,B,C,B,D,A,B)
Y(B,D,C,A,B,A)
那么最长公共子序列就是:B,C,B,A
算法设计:用动态规划方法解决
最长公共子序列的结构:
设X = { x1 , ... , xm },Y = { y1 , ... , yn }及它们的最长子序列Z = { z1 , ... , zk }则:
1、若 xm = yn , 则 zk = xm = yn,且Z[k-1] 是 X[m-1] 和 Y[n-1] 的最长公共子序列
2、若 xm != yn ,且 zk != xm , 则 Z 是 X[m-1] 和 Y 的最长公共子序列
3、若 xm != yn , 且 zk != yn , 则 Z 是 Y[n-1] 和 X 的最长公共子序列
子问题的递归结构:
当 i = 0 , j = 0 时 , c[i][j] = 0
当 i , j > 0 ; xi = yi 时 , c[i][j] = c[i-1][j-1] + 1
当 i , j > 0 ; xi != yi 时 , c[i][j] = max { c[i][j-1] , c[i-1][j] }
还是以:X(A,B,C,B,D,A,B)
Y(B,D,C,A,B,A) 为例
#include <stdio.h>
#include <string.h>
#define MAX_LEN 1000
char sz1[MAX_LEN];
char sz2[MAX_LEN];
int aMaxLen[MAX_LEN][MAX_LEN];
void main()
{
while (scanf("%s%s",sz1+1,sz2+1)>0)
{
int nLength1 = strlen(sz1 +1) ;
int nLength2 = strlen(sz2 + 1) ;
int nTmp ;
int i,j;
for (i=0;i<= nLength1;++i)
{
aMaxLen[i][0] = 0;
}
for (j=0;j<=nLength2; ++j)
{
aMaxLen[0][j] = 0;
}
for (i=1;i<=nLength1;++i)
{
for (j=1;j<=nLength2;++j)
{
if (sz1[i] == sz2[j])
{
aMaxLen[i][j] =aMaxLen[i-1][j-1] + 1 ;
}
else
{
int nLen1 = aMaxLen[i][j-1] ;
int nLen2 = aMaxLen[i-1][j] ;
if (nLen1 > nLen2)
{
aMaxLen[i][j] = nLen1 ;
}
else
{
aMaxLen[i][j] = nLen2 ;
}
}
}
}
/* for (i=0;i<=nLength1;++i)
{
for (j=0;j<=nLength2;++j)
{
printf("%d ",aMaxLen[i][j]);
}
printf("\n");
}*/
printf("%d\n",aMaxLen[nLength1][nLength2]);
}
}