问题描述:
给定两个序列x=(x1,x2,...,xm)和y=(y1,y2,...,yn),z=(z1,z2,...,zx)为x 和y的任意最长公共子序列(LCS),c[i,j]表示xi和yj的LCS的长度,b[i,j]指向表项对应计算C[i,j]时所选的子问题的最优解。
子问题分解如下:
(1)若xm=yn,则zk=xm=yn且zk-1是xm-1和yn-1的一个LCS;
(2)若xm!=yn,则zk!=xm意味着z是xm-1和y的一个LCS;
(3)若xm!=yn,则zk!=yn意味着z是x和yn-1的一个LCS。
下面是源码:
lcs.h
#include<stdio.h>
#include<stdlib.h>
void lcsLength(char *x,char *y,int m,int n,int **c);
void printLCS(int **c,char *x,int i,int j);
lcs.cpp
#include"lcs.h"
void lcsLength(char *x,char *y,int m,int n,int **c){
int i,j;
for(i=0;i<m+1;i++)
c[i][0]=0;
for(j=0;j<m+1;j++)
c[0][j]=0;
for(i=0;i<m;i++)
for(j=0;j<n;j++){
if(x[i]==y[j]){
c[i+1][j+1]=c[i][j]+1;
}
else if(c[i][j+1]>=c[i+1][j]){
c[i+1][j+1]=c[i][j+1];
}
else{
c[i+1][j+1]=c[i+1][j];
}
}
}
void printLCS(int **c,char *x,int i,int j){
if(i==0||j==0)
return ;
if(c[i+1][j+1]==c[i][j]+1){
printLCS(c,x,i-1,j-1);
printf("%c",x[i]);
}
else if(c[i+1][j+1]==c[i][j+1]){
printLCS(c,x,i-1,j);
}
else
printLCS(c,x,i,j-1);
}
main.cpp
#include"lcs.h"
int main(){
char *x,*y;
int i;
int m,n;
int **c;
printf("Please input the length of the sequence x and the sequence y:\n");
scanf("%d %d",&m,&n);
getchar();
x=(char *)malloc(sizeof(char)*m);
printf("Please input the sequence x:\n");
for(i=0;i<m;i++)
scanf("%c",&x[i]);
getchar();
y=(char *)malloc(sizeof(char)*n);
printf("Please input the sequence y:\n");
for(i=0;i<n;i++)
scanf("%c",&y[i]);
c=(int **)malloc(sizeof(int *)*(m+1));
for(i=0;i<m+1;i++)
c[i]=(int *)malloc(sizeof(int)*(n+1));
lcsLength(x,y,m,n,c);
printLCS(c,x,m-1,n-1);
system("pause");
return 0;
}
给一个测试用例:
x={A,B,C,B,D,A,B}
y={B,D,C,A,B,A}
最长公共子序列为:B,C,B,A