LCS最長公共子序列的延伸情況(可連續的子序列)


     看過《算法導論》的人應該知道,動態規划中一個非常經典的例子就是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]的值隨時可能在某個時刻被清零。

    說了這么多,把狀態轉移方程寫出來吧:

 

    偽代碼的話,也比較簡單。

 1 STRICT-LCS-LENGTH(X, Y)
 2 m = length[X]
 3 m = length[Y]
 4 for i = 1 to m
 5     do c[i, 0] = 0
 6 for j = 0 to n
 7     do c[0, j] = 0
 8 for i = 1 to m
 9     do for j = 1 to n
10         do if Xi=Yj
11             then c[i, j] = c[i-1, j-1]+1
12             else c[i, j] = 0
13 return c

  

    下面做一個顯示推導過程的圖。 

   

    從上圖中可以找到值最大的格子2,故可知X和Y的最長公共連續子序列為BD,和AB,兩個子序列的長度都為2.

e


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM