看完演算法導論關於這部分內容之後的總結:
關於最長公共子串行問題:
給定兩個子串行 x=; y=,求x和y長度最長的公共子串行。
解決方法:
首先先要了解lcs的最優子結構,令x=; y=為兩個子串行,z = 為x和y的任意lcs。
1、如果 xm = yn , 則 zk = xm = yn 且 zk-1 是 xm-1 和 yn-1 的乙個lcs;
2、如果 xm ≠ yn , 則 zk ≠ xm ,意味著 z 是xm-1和y 的乙個lcs;
3、如果 xm ≠ yn , 則 zk ≠ yn ,意味著 z 是x和yn-1 的乙個lcs;
求解最長公共子串行主要用到以下公式
偽**分析
lcs_length(x,y)
1、 m = x.length
2、 n = y.length
3、 for i = 1 to m
4、 c[i,0] = 0 //c計算表項
5、 for j =0 to m
6、 c[0,j] = 0
7、 for i = 1 to m
8、 for j = 1 to n
9、 if xi == yj //先比較xi 和 yj 是否相等
10、 c[i,j] = c[i-1][j-1] + 1 //相等的話就將c[i,j]的值加上其上乙個對角線元素的值
11、 b[i,j] = "↖" //並將當前單元格設定成"↖"
12、 elseif c[i-1][j] ≥ c[i][j-1] //xi 和 yj 不相等,則比較當前單元格上方和左方單元格的值
13、 c[i,j] = c[i-1][j] //如果上方單元格的值大於等於其左方單元格的值,則當前單元格設定成"↑"
14、 b[i][j] = "↑"
15、 else
16、 c[i][j] = c[i][j-1]
17、 b[i][j] = "←" //否則設定成"←"
18、return c and b
根據以上偽**構造出的表
執行4,5行後得到下面這個表:j0
1234
56iyj
bdca
ba0xi
0000
0001
a02b
03c0
4b05
d06a
07b0
然後以行為主序開始掃瞄:
我們可以先找出 xi == yj 的單元格,標記它的值和箭頭方向 。
當i = 1時,掃瞄第一行中為(a,a)的單元格,標記為↖,並執行c[i][j] = c[i-1][j-1] + 1;
其它的單元格按照12-17行的**進行標記,如(x1,y1) = (a,b),兩者不相同,所以比較(x1,y1)上方和左方的單元格的值。哪個的值大,箭頭就指向哪個單元格,並將c[i][j]的值設定為c[i-1,j],c[i,j-1]中具有較大值的單元格的值。 j0
1234
56iyj
bdca
ba0xi
0000
0001
a0↑0↑0
↑0↖1
←1↖12b
03c0
4b05
d06a
07b0
當 i = 2時,按照以上方法進行單元格賦值。
最後得到以下**:j0
1234
56iyj
bdca
ba0xi
0000
0001
a0↑0↑0
↑0↖1
←1↖12b
03c0
4b05
d06a
07b0
j012345
6iyjb
dcab
a0xi0
0000
001a
0↑0↑0↑0
↖1←1↖12
b0↖1←1
←1↑1
↖2←23c
0↑1↑1↖2
←2↑2↑24
b0↖1↑1
↑2↑2
↖3←35d
0↑1↖2↑2
↑2↑3↑36
a0↑1↑2
↑2↖3
↑3↖47b
0↖1↑2↑2
↑3↖4
↑
得到上面的**之後,執行以下函式得到lcs
print-lcs(b, x, x.length, y.length)
1、if x.length==0 || y.length == 0
2、 return;
3、if b[i,j] == "↖"
4、 print-lcs(b, x, x.length-1, y.length-1)
5、 print xi
6、elseif b[i,j] == "↑"
7、 print-lcs(b, x, x.length-1, y.length)
8、else
9、 print-lcs(b, x, x.length, y.length-1)j0
1234
56iyj
bdca
ba0xi
0000
0001
a0↑0↑0
↑0↖1
←1↖12b
03c0
4b05
d06a
07b0
動態規劃 最長公共子串行
問題描述 我們稱序列z z1,z2,zk 是序列x x1,x2,xm 的子串行當且僅當存在嚴格上公升的序列 i1,i2,ik 使得對j 1,2,k,有xij zj。比如z a,b,f,c 是x a,b,c,f,b,c 的子串行。現在給出兩個序列x和y,你的任務是找到x和y的最大公共子串行,也就是說要...
動態規劃 最長公共子串行
兩個序列的最長公共子序 lcs longest common length 的 每個字元可以不連續,如x y 那麼它們的最長公共子串行為。這是乙個經典的動態規劃問題,著手點還是找到 最精髓的 狀態轉移方程 假設x,y兩個序列的前i,j個位置的最大子串行已經找到為r i j 自底往上 那麼x i 與y...
動態規劃 最長公共子串行
題目大意不再贅述,即判斷兩個字串,求出字串中最長的公共子串行。這是動態規劃的經典題目。include iostream include cstring using namespace std char sz1 1000 abcfbc char sz2 1000 abfcab int maxlen 1...