最長公共子串行和最長公共子串是有區別的,之前我一直把它們混淆。
最長公共子串舉例:假設s1=,s2=
那麼它們的最長公共子串就是。這是我通常理解的東西。
最長公共子串行。
最長公共子串行舉例:假設s1=,s2=,那麼它們的lcs就是。
這是乙個動態規劃問題。如何求解最長公共子串行(以下用lcs代替)呢?我們假設已經知道z=是x=和y=的lcs,那麼可以分以下三種情況討論(具體每種情況證明不再累述):
xm=yn=zk:那麼zk-1是xm-1和yn-1的lcs。
xm≠yn,yn≠zk:我們可以把yn去掉,那麼zk是xm和yn-1的lcs。
xm≠yn,xm≠zk:我們可以把xm去掉,那麼zk是xm-1和yn的lcs。
基於以上情況,我們可以得到lcs遞迴式。我們假設ci表示xi和yi的lcs長度,那麼:
這樣就可以根據bm反向追蹤lcs,當bi=1,輸出xi;當bi=2,追蹤ci;當bi=3,追蹤ci-1,直到i=0或j=0停止。
(1)初始化。初始化c第1行和第1列為0。
(2)開始操作。具體是將s1[i]分別與s2[j-1](j=1,2,...,len2)進行比較,若字元相等ci=左上角數值+1,且bi=1;若不相等,則ci等於左側或者上側重最大的乙個數值,若左側和上側相等,則取左側,且bi=2或3(當取左側為2,取上側為3)。最後的c和b如下所示:
下表是c:01
2345
6000
0000
a001
1111
b011
1122
c011
2222
a012
2223
d012
2333
a012
2334
b012
2344
下表是b:01
2345
6000
0000
1021
2221
2012
2212
3032
1222
4031
2221
5033
2122
6031
2321
7013
2312
根據c可以得出,lcs的長度為4(也就是c最後乙個值)。然後開始判斷內容是什麼,這是要根據b來。
首先,b7=2,向左找b7=1,所以向左上角找b6,得到字母為s1[6]=[b];
b6=3,向上找b5=1,向左上角找b4,得到字母s1[4]=[d];
b4=2,向左找b4[1],得到字母s1[3]=[a];
b3=3,向上找b2=1,向左上角找b1,得到字母s1[1]=[b].
由於b1=0,所以演算法停止,返回結果為「badb」。
1int commonorder(char x, int m, char y, int n, charz)2
9for(i = 0, i < m; ++i)
1013
for(i = 1; i <= m; ++i)
1422
else
if(l[i][j-1] >= l[i-1
][j])
2327
else
283233}
34}35 k =l[m][n];
36while(m > 0 && n > 0)37
45else
if(s[m][n] == 1) --n;
46else --m;47}
48for(k = 0; k < l[m][n]; ++k)
4952
return
l[m][n];
53 }
最長公共子串行 動態規劃
經常會遇到複雜問題不能簡單地分解成幾個子問題,而會分解出一系列的子問題。簡單地採用把大問題分解成子問題,並綜合子問題的解匯出大問題的解的方法,問題求解耗時會按問題規模呈冪級數增加。為了節約重複求相同子問題的時間,引入乙個陣列,不管它們是否對最終解有用,把所有子問題的解存於該陣列中,這就是動態規劃法所...
最長公共子串行 動態規劃
關於用動態規劃法求兩個序列的最長公共子串行問題的相關知識見 王曉東 計算機演算法設計與分析 第三章。注意,這裡所指的最長公共子串行是可以不相鄰的,與平常所說的最長公共子串 相鄰的 不一樣。直接上 lcs.h ifndef lcs h define lcs h class lcstring endif...
最長公共子串行(動態規劃)
定義 乙個數列 如果分別是兩個或多個已知數列的子串行,且是所有符合此條件序列中最長的,則 稱為已知序列的最長公共子串行。考慮最長公共子串行問題如何分解成子問題,設a a0,a1,am 1 b b0,b1,bm 1 並z z0,z1,zk 1 為它們的最長公共子串行。不難證明有以下性質 1 如果am ...