C语言 分治法--最长公共子序列
- 分析并掌握“最长公共子序列” 问题的动态规划算法求解方法;
- 最长公共子序列问题:若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:zj=xij。例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。
给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。
给定2个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最长公共子序列。
参考程序:
void LCSLength (char *x ,char *y, int m, int n, int **c, int **b)
{
int i ,j;
for (i = 1; 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]==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;
}
}
}
void LCS(int i ,int j, char *x ,int **b)
{
if (i ==0 || j==0) return;
if (b[i][j]== 1)
{
LCS(i-1,j-1,x,b);
printf("%c",x[i]);
}
else if (b[i][j]== 2)
LCS(i-1,j,x,b);
else LCS(i,j-1,x,b);
}
具体代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100
void LCSLength(char *x,char *y,int m,int n,int **c,int **b)
{
int i,j;
for(i=0;i<=m;i++)c[i][0]=0,b[i][0]=0;
for(i=0;i<=n;i++)c[0][i]=0,b[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;
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;
}
}
printf("c[][]序列为:\n");
for(i=0;i<=m;i++)
{
for(j=0;j<=n;j++)
printf("%d\t",c[i][j]);
printf("\n");
}
printf("b[][]序列为:\n");
for(i=0;i<=m;i++)
{
for(j=0;j<=n;j++)
printf("%d\t",b[i][j]);
printf("\n");
}
}
void LCS(int i,int j,char *x,int **b)
{
if(i==0||j==0)return;
if(b[i][j]==1)
{
LCS(i-1,j-1,x,b);
printf("%c ",x[i-1]);
}
else if(b[i][j]==2)LCS(i-1,j,x,b);
else LCS(i,j-1,x,b);
}
void main()
{
int m,n;
int i;
char x[MAX],y[MAX];
printf("x序列为:");
gets(x);
printf("\ny序列为:");
gets(y);
printf("\n");
m=strlen(x);
n=strlen(y);
int **b = new int*[m+1];
for(i= 0; i <m+1; i++)
b[i] = new int[n+1];
int **c = new int*[m+1];
for(i= 0; i < m+1; i++)
c[i] = new int[n+1];
LCSLength(x,y,m,n,c,b);
printf("最长公共子序列为:");
LCS(m,n,x,b);
printf("\n");
for(i=0;i<m+1;i++)
delete []b[i];
delete []b;
for(i=0;i<m+1;i++)
delete []c[i];
delete []c;
}
结果截图: