转自:http://www.cnblogs.com/grenet/archive/2011/03/11/1964417.html
在参阅《A Longest Common Subsequence Algorithm Suitable for Similar Text Strings》(Narao Nakatsu,Yahiko Kambayashi,Shuzo Yajima著)后。发现该算法可以利用线性空间求出最长公共子序列。该算法的时间占用O(n(m-p+1)),p为最长公共子序列的长度。
字符串A和字符串B,计算LCS(A,B)
定义一:设M=Len(A),N=Len(B),不妨设M≤N。
定义二:A=a1a2……aM,表示A是由a1a2……aM这M个字符组成
B=b1b2……bN,表示B是由b1b2……bN这N个字符组成
LCS(i,j)=LCS(a1a2……ai,b1b2……bj),其中1≤i≤M,1≤j≤N
定义三:L(k,i)表示,所有与字符串a1a2……ai有长度为k的LCS的字符串b1b2……bj中j的最小值。
用公式表示就是:L(k,i)=Min{j} Where LCS(i,j)=k
用一个例子来说明:A="CD",B="CEFDRT"。
很明显的是LCS(2,1)=1,LCS(2,2)=1,LCS(2,3)=1。
满足LCS(2,j)=1这个条件的j有三个,分别是j=1、j=2、j=3。其中j最小值是1。故L(1,2)=1
为了推导L的计算,有下面几个定理。
定理一:任意的i,1≤i≤M。有L(1,i)<L(2,i)<L(3,i)……
定理二:任意的i,1≤i≤M-1。任意的k,1≤k≤M。有L(k,i+1)≤L(k,i)
定理三:任意的i,1≤i≤M-1。任意的k,1≤k≤M-1。有L(k,i)<L(k+1,i+1)
定理四:如果L(k,i+1)存在,则L(k,i+1)的计算公式为
L(k,i+1)=Min{Min{j},L(k,i)} Where {ai+1=bj And j>L(k-1,i)}
上面四个定理证明从略。可以从上面四个定理推导出L的计算。
故,L的计算公式为
①L(1,1)=Min{j} Where {a1=bj}
②L(1,i)=Min{Min{j} Where {ai=bj},L(1,i-1)} 此时,1<i≤M
③L(k,i)=Min{Min{j} Where {ai=bj And j>L(k-1,i-1)},L(k,i-1)} 此时,1<i≤M,1<k≤M
注:以上公式中,若找不到满足Where后面条件的j,则j=MaxValue
当i<k时,则L(k,i)=MaxValue
MaxValue是一个常量,表示“不存在”
在实际的算法实现中,为了简化运算,再次提出几个定义。
定义: L(0,i)=0 1≤i≤M
L(k,0)=MaxValue 1<k≤M
MaxValue=N+1 (只要定义一个j不可能取到的值就可以了)
则,在①中的公式可以写成
L(1,1)=Min{j} Where {a1=bj}=Min{j} Where {a1=bj And j>0 }
=Min{Min{j} Where {a1=bj And j>0 },MaxValue}
=Min{Min{j} Where {a1=bj And j>L(0,0) },L(1,0)}
在②中的公式可以写成
L(1,i)=Min{Min{j} Where {ai=bj},L(1,i-1)}
=Min{Min{j} Where {ai=bj And j>0},L(1,i-1)}
=Min{Min{j} Where {ai=bj And j>L(0,i)},L(1,i-1)} 此时,1<i≤M
于是,三个公式统一了
④L(k,i)=Min{Min{j} Where {ai=bj And j>L(k-1,i-1)},L(k,i-1)} 此时,1≤i≤M,1≤k≤M
且当i<k时,则L(k,i)=MaxValue
仔细观察④,公式还可以写成如下
⑤ L(k,i)=Min{j} Where {ai=bj And L(k-1,i-1)<j<L(k,i-1)} 1≤i≤M,1≤k≤M,且j存在
或 L(k,i)=L(k,i-1) 1≤i≤M,1≤k≤M,当j不存在时
写成⑤的目的有两个:一个是简化计算,不计算不必要的值;一个是为了标记,为后面计算最长公共子序列做准备。
接下来,将会用例子来说明:
A:481234781;B:4411327431
第一步:初始化L矩阵
4 | 8 | 1 | 2 | 3 | 4 | 7 | 8 | 1 | ||
---|---|---|---|---|---|---|---|---|---|---|
i=0 | i=1 | i=2 | i=3 | i=4 | i=5 | i=6 | i=7 | i=8 | i=9 | |
k=0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
k=1 | V | |||||||||
k=2 | V | V | ||||||||
k=3 | V | V | V | |||||||
k=4 | V | V | V | V | ||||||
k=5 | V | V | V | V | V | |||||
k=6 | V | V | V | V | V | V | ||||
k=7 | V | V | V | V | V | V | V | |||
k=8 | V | V | V | V | V | V | V | V | ||
k=9 | V | V | V | V | V | V | V | V | V |
第二步:如表格所示,计算第一条对角线
4 | 8 | 1 | 2 | 3 | 4 | 7 | 8 | 1 | ||
---|---|---|---|---|---|---|---|---|---|---|
i=0 | i=1 | i=2 | i=3 | i=4 | i=5 | i=6 | i=7 | i=8 | i=9 | |
k=0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
k=1 | V | 1 | ||||||||
k=2 | V | V | V | |||||||
k=3 | V | V | V | V | ||||||
k=4 | V | V | V | V | V | |||||
k=5 | V | V | V | V | V | V | ||||
k=6 | V | V | V | V | V | V | V | |||
k=7 | V | V | V | V | V | V | V | V | ||
k=8 | V | V | V | V | V | V | V | V | V | |
k=9 | V | V | V | V | V | V | V | V | V | V |
运气很差,只有第一个单元格有值,其余的都是V(MaxValue),很显然这不是问题的解。这条对角线满足L(k-1,i-1)<j<L(k,i-1)的只有一个单元格。先把它标记出来。
第三步:如表格所示,计算相邻的第二条对角线
4 | 8 | 1 | 2 | 3 | 4 | 7 | 8 |
|
---|