/*
LCS:求最长公共子序列
例如:s1="abdrge",s2="adreg",则LCS="adre"
状态方程:lcs(i,j)=lcs(i-1,j-1)+1,其中s1[i]=s2[j]
或者 lcs(i,j)=max{lcs(i,j-1),lcs(i-1,j)}
*/
int LCS(char *a,char *b)
{
int len_a=strlen(a); //行
int len_b=strlen(b); //列
int **len=NULL;
int **r=NULL;
int i=0;
int j=0;
int lcs_len=0;
len=(int **)malloc(sizeof(int *)*(len_a+1)); //申请二维数组空间
r=(int **)malloc(sizeof(int *)*(len_a+1));
if (len==NULL||r==NULL)
return -1;
for(;i<=len_a;i++)
{
*(len+i)=(int *)malloc(sizeof(int)*(len_b+1));
*(r+i)=(int *)malloc(sizeof(int)*(len_b+1));
if (*(len+i)==NULL||*(r+i)==NULL)
return -1;
}
//LCS状态方程
for(i=0;i<=len_a;i++) //初始化
{
for(j=0;j<=len_b;j++)
{
len[i][j]=0;
r[i][j]=0;
}
}
for(i=1;i<=len_a;i++)
{
for(j=1;j<=len_b;j++)
{
if(a[i-1]==b[j-1])
{
len[i][j]=len[i-1][j-1]+1;
r[i][j]=1;
}
else if(len[i][j-1]>=len[i-1][j]) //左边的大于等于上边的
{
len[i][j]=len[i][j-1];
r[i][j]=2;
}
else
{
len[i][j]=len[i-1][j];
r[i][j]=3;
}
}
}
//打印公共子序列
print_lcs(r,a,len_a,len_b);
free(r);
lcs_len= len[len_a][len_b];
free(len);
return lcs_len;
}
void print_lcs(int **r,char *a,int i,int j)
{
if(i==0||j==0)
return ;
else if(r[i][j]==1)
{
print_lcs(r,a,i-1,j-1);
printf("%c",*(a+i-1));
}
else if(r[i][j]==2)
print_lcs(r,a,i,j-1);
else
print_lcs(r,a,i-1,j);
}
DP实例之最长公共子序列LCS
最新推荐文章于 2021-05-06 20:50:23 发布