若给定序列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的最长公共子序列。
m[0...m,0]=0;
m[0,0...n]=0;
if(x[i]==y[j])
m[i,j]=m[i-1,j-1]+1;
else if m[i,j-1]>=m[i-1,j]
m[i,j]=m[i,j-1]
else
m[i,j]=m[i-1,j]
#include <stdio.h>
#include <string.h>
#define MAXLINE 100
//求最长子序列的长度。辅助二维数组b[][]是用来在print函数中输出的
//时候用的
void LCSlength(int n,int m,char *x,char *y,int c[][MAXLINE],int b[][MAXLINE]){
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++){
if(j==0||i==0)
c[i][j]=0;
else
if(x[i-1]==y[j-1]){
c[i][j]=c[i - 1][j - 1]+1;
b[i][j]=1;
}
else{
if(c[i][j-1]>=c[i-1][j])
{
c[i][j]=c[i][j-1];
b[i][j]=2;
}
else{
c[i][j]=c[i-1][j];
b[i][j]=3;
}
}
}
return;
}
void LCS(int i,int j,int b[][MAXLINE],char *x,char *y){
if(i==0||j==0) return;
if(b[i][j]==1)
{
LCS(i-1, j-1, b, x, y);
printf("%c ", x[i-1]);
}
else if(b[i][j]==2)
{
LCS(i, j-1, b, x, y);
}
else{
LCS(i-1, j, b, x, y);
}
}
int main() {
char x[]="ABCBDAB";
char y[]="BDCABA";
int n=strlen(x);
int m=strlen(y);
int c[MAXLINE][MAXLINE];
int b[MAXLINE][MAXLINE];
LCSlength(n, m, x, y, c, b);
LCS(n, m, b, x, y);
return 0;
}