動態規劃 最長公共子串行

2021-07-04 02:19:31 字數 2910 閱讀 3209

看完演算法導論關於這部分內容之後的總結:    

關於最長公共子串行問題:

給定兩個子串行 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...