動態規劃 最長公共子串行與最長公共子串

2021-07-27 00:05:56 字數 2117 閱讀 7996

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

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

對於母串

x=,x2,

⋯,xm

>

, y=,y2,

⋯,yn

>

,求lcs與最長公共子串。

假設 m

<

n

, 對於母串x

,我們可以暴力找出2m

個子序列,然後依次在母串y

中匹配,演算法的時間複雜度會達到指數級o(

n∗2m

) 。顯然,暴力求解不太適用於此類問題。假設z

=,z2,

⋯,zk

>

是x

與y

的lcs, 我們觀察到 ,則

zk=x

m=yn

,有zk

−1 是

xm−1

與yn−1

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

用二維陣列c[i][j]記錄串x1x

2⋯xi

與y1y2⋯y

j

的lcs長度,則可得到狀態轉移方程c[

i,j]

=⎧⎩⎨

⎪⎪0c

[i−1

,j−1

]+1max(c

[i,j

−1],

c[i−

1,j]

)i=0

orj=

0i,j

>0a

ndxi

=yji

,j>0a

ndxi

≠yj

**實現

public

static

intlcs

(string str1, string str2)

else

if (str1.charat(i-1) == str2.charat(j-1)) else }}

return c[len1][len2];

}

前面提到了子串是一種特殊的子串行,因此同樣可以用dp來解決。定義陣列的儲存含義對於後面推導轉移方程顯得尤為重要,糟糕的陣列定義會導致異常繁雜的轉移方程。考慮到子串的連續性,將二維陣列c[i

,j]

用來記錄具有這樣特點的子串——結尾為母串x1x

2⋯xi

與y1y2⋯y

j

的結尾——的長度。

得到轉移方程:

c[i,j]=

⎧⎩⎨⎪

⎪0c[

i−1,

j−1]

+10i

=0or

j=0x

i=yj

xi≠y

j

最長公共子串的長度為 max

(c[i

,j])

,i∈,

j∈。**實現

public

static

intlcs

(string str1, string str2)

else

if (str1.charat(i-1

) == str2.charat(j-1

)) else}}

return

result;

}

最長公共子串與最長公共子串行問題(動態規劃)

公共子串是連續的,而公共子串行不是連續的。x1 abcc x2 acbcc x1和x2的公共子串為 bcc 公共子串行為 abcc 我們來看一下兩個問題的轉移方程 最長公共子串 dp i j 0 if i 0 or j 0 dp i j dp i 1 j 1 1 if x1 i x2 j dp i ...

動態規劃之最長公共子串行 最長公共子串

題目 如果字串1的所有字元按其在字串中的順序出現在另外乙個字串2中,則字串1稱之為字串2的子串行。注意,並不要求子子串行 字串1 的字元必須連續出現在字串2中。請編寫乙個函式,輸入兩個字串,求它們的最長公共子串,並列印出最長公共子串行。例如 輸入兩個字串bdcaba和abcbdab,字串bcba和b...

動態規劃 最長公共子串行和最長公共子串

我們首先需要搞清楚以下兩個概念 最長公共子串行 vs 最長公共子串 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。問題描述 給定兩個字串,求解這兩個字串的最長公共子串行 longest common sequence 比如字串1 bdcaba 字串2 ab...