最長公共子串行

2021-08-28 10:27:45 字數 1671 閱讀 6873

題目描述

給你乙個序列x和另乙個序列z,當z中的所有元素都在x中存在,並且在x中的下標順序是嚴格遞增的,那麼就把z叫做x的子串行。

例如:z=是序列x=的乙個子串行,z中的元素在x中的下標序列為<1,2,4,6>。

現給你兩個序列x和y,請問它們的最長公共子串行的長度是多少?

輸入輸入包含多組測試資料。每組輸入佔一行,為兩個字串,由若干個空格分隔。每個字串的長度不超過100。

輸出對於每組輸入,輸出兩個字串的最長公共子串行的長度。

樣例輸入

abcfbc abfcab

programming contest

abcd mnp

樣例輸出

4

20

ac**:

#include

#include

int c=0;

int str(int x,char a,int y,char b);

int max(int s,int w);

int main()

return 0;

}int str(int x,char a,int y,char b)

else if(a[i-1]==b[j-1])

else}}

return c[x][y];

}int max(int s,int w)

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

比如序列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)。

最長公共子串行 最長公共子串

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...

最長公共子串行 最長公共子串

1.區別 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。2 最長公共子串 其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公...

最長公共子串 最長公共子串行

子串要求連續 子串行不要求連續 之前的做法是dp求子序列 include include include using namespace std const int inf 0x3f3f3f3f const int mod 1000000007 string s1,s2 int dp 1010 10...