您的位置:首页 > 其它

LCS最长公共子序列的延伸情况(可连续的子序列)

2012-10-30 21:16 197 查看
看过《算法导论》的人应该知道,动态规划中一个非常经典的例子就是LCS(Longest Common Length)最长公共子序列问题。下面我们来回顾一下LCS的概念。

假设有两个字符串,X=<A, B, C, B, D, A, B>,Y=<B, D, C, A, B, A>,那么它们的最长公共子序列为<B, C, B, A>,它的特点在于每个字符可以不连续。LCS问题在实际中也有非常多的应用,比如说用于论文查重等。

都说表达一个动态规划算法的精髓在于状态转移方程,那么我们就顺便回忆一下LCS的状态转移方程吧。如果用c[i, j]来表示序列Xi和Yi的LCS的长度,那么有状态转移方程:



下面进入本文的重点。如果将LCS的条件加严,要求子序列中的字符必须是连续的。那么应该如何求解这个最长公共连续子序列呢?

为了便于书写,后文中再提到“最长公共连续子序列”,我都一律用STRICT-LCS代替。

为了便于理解,还是用之前的两个字符串来举例说明什么是STRICT-LCS。X=<A, B, C, B, D, A, B>,Y=<B, D, C, A, B, A>。那么它们的最长公共连续子序列为<B, D>。

我们仍然用Dynamic Programming求解。只不过在原来的基础上需要改变。首先,我们定义c[i, j]跟原来的意义略有不同。这里c[i, j]指的是最后一个元素为Xi(=Yj)的STRICT-LCS的长度,比如X=<A, B, C>,Y=<A, B, D>那么c[3, 3]=0,不管前面如何,如果Xi和Yj不相等,就得将c[i, j]清零,作为新的开始。

LCS中,c[i, j]的值随着i、j值增大而渐渐增大,有累计效应;但是STRICT-LCS中,c[i, j]的值随时可能在某个时刻被清零。

说了这么多,把状态转移方程写出来吧:



伪代码的话,也比较简单。

STRICT-LCS-LENGTH(X, Y)
m = length[X]
m = length[Y]
for i = 1 to m
do c[i, 0] = 0
for j = 0 to n
do c[0, j] = 0
for i = 1 to m
do for j = 1 to n
do if Xi=Yj
then c[i, j] = c[i-1, j-1]+1
else c[i, j] = 0
return c


下面做一个显示推导过程的图。



从上图中可以找到值最大的格子2,故可知X和Y的最长公共连续子序列为BD,和AB,两个子序列的长度都为2.

e
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: