由算法 LCSLength 计算得到的数组 b 可用于快速构造序列X={x1,x2,…,xm}和Y={y1,y2,...,yn}的最长公共子序列。首先从b[m][n]开始,依其值在数组b中搜索。当在b[i][j]=1时,时,表示Xi和Yj的最长公共子序列是由Xi-1和Yj-1的最长公共子序列在尾部加上xi所得到
的子序列。当b[i][j]=2时,表示Xi和Yi和的最长公共子序列与Xi-1和Yj的最长公共子序列相
同。当b[i][j]=3时,表示Xi和Yi的最长公共子序列与Xi和Yj-1的最长公共子序列相同。
下面的算法 LCS 实现根据 b的内容打印出Xi和Yj,和的最长公共子序列。通过算法调用
LCS(m,n,x,b)便可打印出序列X和Y的最长公共子序列。
#include<stdio.h>
#include<string.h>
int c[200][200];
int b[200][200];
char f[200];
int Max(int m,int n,int i,int j)
{
if(m > n)
{
b[i][j] = -1;
return m;
}
else
{
b[i][j] = 1;
return n;
}
}
void print(int i,int j,int s,char x[],char y[])
{
if(b[i][j] == 0)
{
f[s-1] = x[i-1];
i--;j--;s--;
print(i,j,s,x,y);
}
else if(b[i][j] == -1)
{
i--;
print(i,j,s,x,y);
}
else if(b[i][j] == 1)
{
j--;
print(i,j,s,x,y);
}
}
int LCS(char x[],char y[])
{
int i,j;
int x_len,y_len;
x_len = strlen(x);
y_len = strlen(y);
printf(" ");
for(i = 0;i < y_len;i++)
{
printf("%c ",y[i]);
}
printf("\n");
for(i = 1;i <= x_len;i++)
{
printf("%c ",x[i-1]);
for(j = 1;j <= y_len;j++)
{
if(x[i-1] == y[j-1])
{
c[i][j] = c[i-1][j-1] +1;
b[i][j] = 0;
printf("%d ",c[i][j]);
}
else
{
c[i][j] = Max(c[i-1][j],c[i][j-1],i,j);
printf("%d ",c[i][j]);
}
}
printf("\n");
}
//打印X和Y的LCS
printf("X和Y的LCS是:");
print(x_len,y_len,c[x_len][y_len],x,y);
printf("%s",f);
printf("\n");
return c[x_len][y_len];
}
int main()
{
char X[200],Y[200];
int i,j,s;
printf("请输入字符串X:");
scanf("%s",X);
printf("请输入字符串Y:");
scanf("%s",Y);
s = LCS(X,Y);
printf("X和Y的LCS: %d \n",s);
}
在算法LCS中,每次递归调用使i或j减1,因此算法的计算时间为O(m+n)。