0
点赞
收藏
分享

微信扫一扫

动态规划——最长公共子序列(算法设计课题)


问题描述:

若给定序列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的最长公共子序列。

解题思路:

设序列X={x1,x2,…,xm}和Y={y1,y2,…,yn}的最长公共子序列为Z={z1,z2,…,zk} ,则
(1)若xm=yn,则zk=xm=yn,且zk-1是xm-1和yn-1的最长公共子序列。
(2)若xm≠yn且zk≠xm,则Z是xm-1和Y的最长公共子序列。
(3)若xm≠yn且zk≠yn,则Z是X和yn-1的最长公共子序列。

动态规划——最长公共子序列(算法设计课题)_动态规划


由于在所考虑的子问题空间中,总共有θ(mn)个不同的子问题,因此,用动态规划算法自底向上地计算最优值能提高算法的效率。

#include<stdio.h>
#include<string.h>
#define MAXLEN 100
void LCSLength(char *x, char *y, int m, int n, int c[][MAXLEN], int b[][MAXLEN])
{
int i, j;
for(i = 0; i <= m; i++)
c[i][0] = 0;
for(j = 1; j <= n; j++)
c[0][j] = 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;
}
}
}
}
void PrintLCS(int b[][MAXLEN],char *x,int i,int j)
{
if(i==0||j==0)
return;
if(b[i][j]==1)
{
PrintLCS(b,x,i-1,j-1);
printf("%c",x[i-1]);
}
else if(b[i][j]==2)
PrintLCS(b,x,i-1,j);
else
PrintLCS(b,x,i,j-1);
}

int main(int argc, char **argv)
{
char x[MAXLEN];
char y[MAXLEN];
int b[MAXLEN][MAXLEN];
int c[MAXLEN][MAXLEN];
int m,n;

while(-1)
{
gets(x);
gets(y);
m=strlen(x);
n=strlen(y);
LCSLength(x,y,m,n,c,b);
PrintLCS(b,x,m,n);
printf("\n");
}
return 0;
}







举报

相关推荐

0 条评论