一、問題描述
子串應該比較好理解,至於什麼是子串行,這裡給出乙個例子:有兩個母串
cnblogs
belong
比如序列bo, bg, lg在母串cnblogs與belong中都出現過並且出現順序與母串保持一致,我們將其稱為公共子串行。最長公共子串行(longest common subs lcs),顧名思義,是指在所有的子串行中最長的那乙個。子串是要求更嚴格的一種子串行,要求在母串中連續地出現。在上述例子的中,最長公共子串行為blog(cnblogs, belong),最長公共子串為lo(cnblogs, belong)。
二、求解演算法
對於母串x=x=, y=y= ,求lcs與最長公共子串。
暴力解法
假設m, 對於母串xx,我們可以暴力找出2m2m個子序列,然後依次在母串yy中匹配,演算法的時間複雜度會達到指數級o(n∗2m)o(n∗2m)。顯然,暴力求解不太適用於此類問題。
動態規劃
假設z=z=是xx與yy的lcs, 我們觀察到www.cppcns.com
如果xm=ynxm=yn,則zk=xm=ynzk=xm=yn,有zk−1zk−1是xm−1xm−1與yn−1yn−1的lcs;
如果xm≠ynxm≠yn,則zkzk是xmxm與yn−1yn−1的lcs,或者是xm−1xm−1與ynyn的lcs。
因此,求解lcs的問題則變成遞迴求解的兩個子問題。但是,上述的遞迴求解的辦法中,重複的子問題多,效率低下。改進的辦法——用空間換時間,用陣列儲存中間狀態,方便後面的計算。這就是動態規劃(dp)的核心思想了。
dp 求解 lcs
用二維陣列c[i][j]記錄串x1x2⋯xix1x2⋯xi與y1y2⋯yjy1y2⋯yj的lcs長度,則可得到狀態轉移方程
**實現
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⋯xix1x2⋯xi與y1y2⋯yjy1y2⋯yj的結尾——的長度。
得到轉移方程:
最長公共子串的長度為max(c[i,j]), i∈,j∈max(c[i,j]), i∈,j∈。
**實現
public static int lcs(string str1, string str2) else if (str1.charat(i-1) == str2.charat(j-1)) else
} }return result;}總結
本文標題: 利用c++實現最長公共子串行與最長公共子串
本文位址: /ruanjian/c/173426.html
最長公共子串行 與 最長公共子串
最長公共子串行 常用於解決字串的相似度,是指在母串中都出現過並且出現順序與母串保持一致的子串,不要求連續性。最長公共子串 是指在母串中連續出現的子串。例如 cnblogs belong 最長公共子串行為blog,最長公共子串為lo假設z z2,zk 是母串 x 與 y的最長公共子串行lcs,那麼 用...
最長公共子串與最長公共子串行
一 最長公共子串 longest common substring 遍歷的時候用乙個二維陣列儲存相應位置的資訊,如果兩個子串1與子串2相應位置相等 則看各自前乙個位置是否相等,相等則該位置值b i j b i 1 j 1 1,不相等則置為1。如果兩個子串1與子串2相應位置不相等,則b i j 0。如...
最長公共子串行 最長公共子串
1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...