最长公共子序列(Longest Common Subsequence)

一个给定序列的子序列就是该给定序列中去掉零个或者多个元素。

给定一个序列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 }
posted @ 2012-02-07 10:34  Cavia  阅读(336)  评论(0编辑  收藏  举报