最長公共子串行

2021-08-31 18:13:46 字數 1403 閱讀 3054

例:

a=['a','b','c','b','d','a','b']

b=['b','d','c','a','b','a']

最長公共子串行是bcba或bdab,子串行可以不是連續的,相對順序一樣就可以。

這是一道動態規劃題,首先我們需要乙個c[a+1][b+1]來記錄狀態,注意每一維需要比數組長1,為了儲存當a,b為空時候的情況。然後我們從[0,0]開始按行填表。按如下公式進行填表

我們想象一下ab兩個陣列最後乙個元素如果是相同的,那麼它肯定在最長公共子串行裡,那麼問題就縮小為去掉最後乙個元素找子串行的問題。如果最後乙個元素不一樣,這裡就有分支了,我可以從a中去掉乙個,也可以從b中去掉乙個,最後我肯定是要選擇收益最高的那個。

a=['a','b','c','b','d','a','b']

b=['b','d','c','a','b','a']

len_a = len(a)

len_b = len(b)

c=[[0 for i in range(len_b+1)]for j in range(len_a+1)]

for i in range(len_a):

for j in range(len_b):

if a[i] == b[j]:

c[i+1][j+1] = c[i][j] + 1

elif c[i+1][j] > c[i][j+1]:

c[i+1][j+1] = c[i+1][j]

else:

c[i+1][j+1] = c[i][j+1]

i=len_a

j=len_b

ans=

while i>0 and j>0:

if a[i-1]==b[j-1]:

i=i-1

j=j-1

else:

if c[i-1][j]>c[i][j-1]:

i=i-1

else:

j=j-1

print(ans)

#['b', 'a', 'd', 'b']

print (c[len_a][len_b])

#4

最後最長的長度在表中的右下角,現在只得到了長度,如果想獲得具體的序列,還需要回溯。我們從右下角開始,如果a,b元素相同,那麼這個元素就在序列裡,同時它的狀態是從[i-1][j-1]得來的,所以回溯到[i-1][j-1]。如果不相同,就看它是從哪個分支過來的,我們走較大的那個分支。如果兩個分支是相等的,我們就選乙個方向,注意回溯的時候處理相等的情況需要從始至終選定乙個方向,最終回溯到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...

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

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