最長公共子串行(LCS)與最長公共子串 DP

2021-09-01 00:00:08 字數 2280 閱讀 6889

《1》最長公共子串行(lcs)與最長公共子串(dp)

子串應該比較好理解,至於什麼是子串行,這裡給出乙個例子:有兩個母串

比如序列bo, bg, lg在母串cnblogs與belong中都出現過並且出現順序與母串保持一致,我們將其稱為公共子串行。最長公共子串行(longest common subsequence,lcs),顧名思義,是指在所有的子串行中最長的那乙個。子串是要求更嚴格的一種子串行,要求在母串中連續地出現。在上述例子的中,最長公共子串行為blog(cnblogs,belong),最長公共子串為lo(cnblogs, belong)。

對於母串x=, y=,求lcs與最長公共子串。

暴力解法

假設 m是x與y的lcs, 我們觀察到

如果xm=yn,則zk=xm=yn,有zk−1是xm−1與yn−1的lcs;

如果xm≠yn,則zk是xm與yn−1的lcs,或者是xm−1與yn的lcs。

因此,求解lcs的問題則變成遞迴求解的兩個子問題。但是,上述的遞迴求解的辦法中,重複的子問題多,效率低下。改進的辦法——用空間換時間,用陣列儲存中間狀態,方便後面的計算。這就是動態規劃(dp)的核心思想了。

dp求解lcs

用二維陣列c[i][j]記錄串x1x2⋯xi與y1y2⋯yj的lcs長度,則可得到狀態轉移方程

由最長公共子串行問題的最優子結構性質可知,要找出x=和y=的最長公共子串行,可按以下方式遞迴地進行:當xm=yn時,找出xm-1和yn-1的最長公共子串行,然後在其尾部加上xm(=yn)即可得x和y的乙個最長公共子串行。當xm≠yn時,必須解兩個子問題,即找出xm-1和y的乙個最長公共子串行及x和yn-1的乙個最長公共子串行。這兩個公共子串行中較長者即為x和y的乙個最長公共子串行。

在演算法lcs中,每一次的遞迴呼叫使i或j減1,因此演算法的計算時間為o(m+n)。

例如,設所給的兩個序列為x=和y=。由演算法lcs_length和lcs計算出的結果如下圖所示:

**實現

[cpp]view plain

copy

public static int lcs(string str1, string str2)  else if (str1.charat(i-1) == str2.charat(j-1))  else   

}  }  

return c[len1][len2];  

}  dp求解最長公共子串

前面提到了子串是一種特殊的子串行,因此同樣可以用dp來解決。定義陣列的儲存含義對於後面推導轉移方程顯得尤為重要,糟糕的陣列定義會導致異常繁雜的轉移方程。考慮到子串的連續性,將二維陣列c[i][j]用來記錄具有這樣特點的子串——結尾同時也為為串x1x2⋯xi與y1y2⋯yj的結尾——的長度。

得到轉移方程:

最長公共子串的長度為 max(c[i,j]), i∈,j∈。

**實現

3. 參考資料

[1] cs2035, longest common subsequence.

[2] 一線碼農, 經典演算法題每日演練——第四題 最長公共子串行.

[3] geeksforgeeks, dynamic programming | set 29 (longest common substring).

LCS 最長公共子串行

問題描述 我們稱序列z z1,z2,zk 是序列x x1,x2,xm 的子串行當且僅當存在嚴格上 公升的序列 i1,i2,ik 使得對 j 1,2,k,有 xij zj。比如z a,b,f,c 是 x a,b,c,f,b,c 的子串行。現在給出兩個序列 x和 y,你的任務是找到 x和 y的最大公共子...

LCS最長公共子串行

求兩個字串的最大公共子串行問題 子串行的定義 若給定序列x 則另一串行z 是x的子串行是指存在乙個嚴格遞增下標序列使得對於所有j 1,2,k有 zj xij。例如,序列z 是序列x 的子序列,相應的遞增下標序列為。分析 用動態規劃做 1.最長公共子串行的結構 事實上,最長公共子串行問題具有最優子結構...

LCS最長公共子串行

lcs是longest common subsequence的縮寫,即最長公共子串行。乙個序列,如果是兩個或多個已知序列的子串行,且是所有子串行中最長的,則為最長公共子串行。複雜度對於一般的lcs問題,都屬於np問題。當數列的量為一定的時,都可以採用動態規劃去解決。解法動態規劃的乙個計算最長公共子串...