最长公共子序列,是动态规划的一个典型例题。相比原来的遍历查找,优化明显。
1⃣️、两个序列--Am,Bn,如果Am=Bn,则再去Am-1,Bn-1;
2⃣️、An!=Bm,找其中最大组,即max{{An,Bm-1},{An-1,Bm}};
3⃣️、两者其中一个为空,则有CLS=0;
简单应用-----------------------------------医学中DNA相同对比,找出相同的序列
涉及算法:
int b[N][N];
int CSL_Length(Data x[],Data y[],int length1,int length2)
{
int n=length1;
int m=length2;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
b[i][j]=0;
int c[n+1][m+1];
for(int i=0;i<n;i++)
c[i][0]=0;
for(int j=0;j<m;j++)
c[0][j]=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(x[i]==y[j])
{
c[i][j]=c[i-1][j-1]+1;
b[i][j]=1;
}
else if(c[i-1][j]>=c[i][j-1])
{
c[i][j]=c[i-1][j];
b[i][j]=2;
}
else{
c[i][j]=c[i][j-1];
b[i][j]=3;
}
return c[n-1][m-1];
}
void searchList(Data x[],int i,int j)
{
if(b[i][j]==0) return;
if(b[i][j]==1)
{
searchList(x, i-1, j-1);
printf("%c",x[i]);
}
else if(b[i][j]==2)
{
searchList(x, i-1, j);
}
else
{
searchList(x, i, j-1);
}
}
--------------时间复杂度为O(m+n)
用例测试:
char x[8]={'a','a','c','d','e','f'};
char y[8]={'a','b','c','f','e','f','m','\''};
printf("the CLS is %d\n",CSL_Length(x,y,6,8));
searchList(x, 5, 7);
printf("\n");
输出: