以例項說明:字串a=kitten,字串b=sitting
那他們的最長公共子串為ittn(注:最長公共子串不需要連續出現,但一定是出現的順序一致),最長公共子串長度為4。
定義:lcs(a,b)表示字串a和字串b的最長公共子串的長度。很顯然,lsc(a,b)=0表示兩個字串沒有公共部分。
rev(a)表示反轉字串a
len(a)表示字串a的長度
a+b表示連線字串a和字串b
性質:lcs(a,a)=len(a)
lcs(a,」「)=0
lcs(a,b)=lcs(b,a)
0≤lcs(a,b)≤min(len(a),len(b))
lcs(a,b)=lcs(rev(a),rev(b))
lcs(a+c,b+c)=lcs(a,b)+len(c)
lcs(a+b,a+c)=len(a)+lcs(b,c)
lcs(a,b)≥lcs(a,c)+lcs(b,c)
lcs(a+c,b)≥lcs(a,b)+lcs(b,c)
為了講解計算lcs(a,b),特給予以下幾個定義
a=a1a2……an,表示a是由a1a2……an這n個字元組成,len(a)=n
b=b1b2……bm,表示b是由b1b2……bm這m個字元組成,len(b)=m
定義lcs(i,j)=lcs(a1a2……ai,b1b2……bj),其中0≤i≤n,0≤j≤m
故: lcs(n,m)=lcs(a,b)
lcs(0,0)=0
lcs(0,j)=0
lcs(i,0)=0
對於1≤i≤n,1≤j≤m,有公式一
若ai=bj,則lcs(i,j)=lcs(i-1,j-1)+1
若ai≠bj,則lcs(i,j)=max(lcs(i-1,j-1),lcs(i-1,j),lcs(i,j-1))
計算lcs(a,b)的演算法有很多,下面介紹的needleman/wunsch演算法是其中的一種。和ld演算法類似,needleman/wunsch演算法用的都是動態規劃的思想。在needleman/wunsch演算法中還設定了乙個權值,用以區分三種操作(插入、刪除、更改)的優先順序。在下面的演算法中,認為三種操作的優先順序都一樣。故權值預設為1。
舉例說明:a=ggatcga,b=gaattcagtta,計算lcs(a,b)
則,lcs(a,b)=lcs(7,11)=6
可以看出,needleman/wunsch演算法實際上和ld演算法是非常接近的。故他們的時間複雜度和空間複雜度也一樣。時間複雜度為o(mn),空間複雜度為o(mn)。空間複雜度經過優化,可以優化到o(m),但是一旦優化就喪失了計算匹配字串的機會了。由於**和ld演算法幾乎一樣。這裡就不再貼**了。
還是以上面為例a=ggatcga,b=gaattcagtta,lcs(a,b)=6
他們的匹配為:
如上面所示,藍色表示完全匹配,黑色表示編輯操作,_表示插入字元或者是刪除字元操作。如上面所示,藍色字元有6個,表示最長公共子串長度為6。
利用上面的needleman/wunsch演算法矩陣,通過回溯,能找到匹配字串
第一步:定位在矩陣的右下角
若ai≠bj,回溯到左上角、上邊、左邊中值最大的單元格,若有相同最大值的單元格,優先順序按照左上角、上邊、左邊的順序
若當前單元格是在矩陣的第一行,則回溯至左邊的單元格
若當前單元格是在矩陣的第一列,則回溯至上邊的單元格
依照上面的回溯法則,回溯到矩陣的左上角
第三步:根據回溯路徑,寫出匹配字串
若回溯到左上角單元格,將ai新增到匹配字串a,將bj新增到匹配字串b
若回溯到上邊單元格,將ai新增到匹配字串a,將_新增到匹配字串b
若回溯到左邊單元格,將_新增到匹配字串a,將bj新增到匹配字串b
搜尋晚整個匹配路徑,匹配字串也就完成了
ld演算法和needleman/wunsch演算法的回溯路徑是一樣的。這樣找到的匹配字串也是一樣的。
最長公共子串行 最長公共子串
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...