一个给定序列的子序列就是该给定序列中去掉零个或者多个元素。
给定一个序列X={x1,x2,...,xm},对i=0,1...,m,定义X的第i个前缀Xi={x1,x2,...,xi},X0是个空序列。
定理:设X={x1,x2,...,xm}和Y={y1,y2,...,yn}为两个序列,并设Z={z1,z2,...,zk}为X和Y的任意一个LCS。
(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
定义c[i][j]为序列Xi和Yj的一个LCS长度,则递归式为
c[i][j]=0(if i=0 or j=0) or c[i-1][j-1]+1(if i,j>0 and xi=yj) or max(c[i][j-1],c[i-1][j])(if i,j>0 and xi!=yj)
lcs length
1 //c[i][j]保存Xi,Yj的LCS的长度
2 //b[i][j]保存Xi,Yj的LCS长度是由哪一个递归式推导过来的
3
4 LCS-LENGTH(X,Y)
5 m=length(X)
6 n=length(Y)
7 for(i=1;i<=m;++i)
8 c[i][0]=0
9 for(i=1;i<=n;++i)
10 c[0][i]=0
11 for(i=1;i<=m;++i)
12 for(j=1;j<=n;++j)
13 if(X[i]==Y[j])
14 c[i][j]=c[i-1][j-1]+1
15 b[i][j]=0 //case 1
16 else if(c[i-1][j]>=c[i][j-1])
17 c[i][j]=c[i-1][j]
18 b[i][j]=1 //case 2
19 else
20 c[i][j]=c[i][j-1]
21 b[i][j]=2 //case 3
1 PRINT-LCS(b,X,i,j)
2 if(i==0 || j==0)
3 return
4 if(b[i][j]==0) //case 0
5 PRINT-LCS(b,X,i-1,j-1)
6 print X[i]
7 else if(b[i][j]==1) //case 1
8 PRINT-LCS(b,X,i-1,j)
9 else
10 PRINT-LCS(b,X,i,j-1)
11
1 #include <iostream> 2 using namespace std; 3 void PrintLCS(int ** path,int m,int n,char* a,char* b) 4 { 5 if(m==0 || n==0) 6 return; 7 if(path[m][n]==0) 8 { 9 PrintLCS(path,m-1,n-1,a,b); 10 cout <<a[m-1]; 11 } 12 else if(path[m][n]==1) 13 PrintLCS(path,m,n-1,a,b); 14 else 15 PrintLCS(path,m-1,n,a,b); 16 } 17 18 void LCS(char* strA,char* strB) 19 { 20 int lenA=strlen(strA); 21 int lenB=strlen(strB); 22 int **length=new int*[lenA+1]; 23 int **path=new int*[lenA+1]; 24 for(int i=0;i<=lenA;++i) 25 { 26 length[i]=new int[lenB+1]; 27 path[i]=new int[lenB+1]; 28 } 29 for(int i=0;i<=lenA;++i) 30 length[i][0]=0; 31 for(int i=0;i<=lenB;++i) 32 length[0][i]=0; 33 34 for(int i=1;i<=lenA;++i) 35 { 36 for(int j=1;j<=lenB;++j) 37 { 38 if(strA[i-1]==strB[j-1]) 39 { 40 length[i][j]=length[i-1][j-1]+1; 41 path[i][j]=0; 42 } 43 else 44 { 45 if(length[i][j-1]>length[i-1][j]) 46 { 47 length[i][j]=length[i][j-1]; 48 path[i][j]=1; 49 } 50 else 51 { 52 length[i][j]=length[i-1][j]; 53 path[i][j]=2; 54 } 55 } 56 } 57 } 58 cout <<"The LCS is"<<length[lenA][lenB]<<endl; 59 PrintLCS(path,lenA,lenB,strA,strB); 60 cout <<endl; 61 } 62 63 int main() 64 { 65 char str1[50]; 66 char str2[50]; 67 cin >>str1; 68 cin >>str2; 69 LCS(str1,str2); 70 return 0; 71 }