最長公共子串行 動態規劃

2021-09-21 19:37:51 字數 2226 閱讀 1388

參考自

最長公共子串行,就是找出兩個序列中最長的相同序列(不必連續)

比如abtck和aeck的最長子序列就是ack。

查詢出最長公共子串行需要一些數學方法。

首先設想,對於兩個序列

x:x1,x2,x3....xm

y:y1,y2,y3...yn

假設 xm 和 yn 是相同的,那麼只需要找到  xm  -1,和ym-1的最長公共子串行,再加上  yn 就行了。

如果  xm 和  yn 不同,那麼就要計算2次了

先把  xm 去掉,用  xm-1個序列和  yn 算最長公共子串行。再把  xm 去掉,用  yn-1個元素和  xm 算最長公共子串行。

兩種的結果再比較,取較大的那個序列。

因此,可以通過兩個for,來比較任意2個子序列之間的最長公共子串行。

如果用數學公式表達,可以表示為

可以用二維陣列c[i,j]表示截止到x[i]的字串與截止到的y[j] 的字串的最長公共子串行長度。為了便於程式設計,我們隊c[i,0]和c[0,j]上的元素都初始化為0

編寫**後,可以生成如下的乙個表。

先不用去看箭頭。

看x2和y1之間的數字,因為都是b,所以這個值就是斜上角的數字+1=1。說明ab和b之間最長公共子串行長度為1.

再看x2和y2,乙個b乙個d,不相等,那麼就因為c[2,1]比c[1,2]大,所以就還是為1.說明ab和bd之間的最長公共子串行還是為1.

依次類推。直至填滿整個**。

箭頭可以用另乙個二維陣列表示,表示這個長度是從哪來計算出來的,用於後期的回溯。

這個表完成後,要獲取最長公共子串行就只需要回溯此表。按照箭頭的順序就可以了。

回溯的演算法也是依據這樣的乙個事實,即

如果 xm  =  yn ,那麼 xm 就是最長子序列中的乙個值。而且是最後乙個值。

然後找到 xm -1, yn 或者 xm , yn -1這兩組各自的最長公共子串行,去長的那個+ xm 就ok了。

如上圖,先找到x7和y6,由於不相同,就找x6和y6之間的。為啥是x6和y6而不是x7,y5,那是因為x6y6和x7y5的最長公共子串行都是4,所以我們就只約定一種取值方式就可以了。如果取x7,y5,則會導致另一種不同的結果。待會可以從**中看到。

接下來看具體**和結果。**的backtrack1和backtrack2其實是等價的。

此處我們定義的是如果(c[i - 1, j] >= c[i, j - 1])就按照向上的路徑走。

如果我們改為c[i - 1, j] == c[i, j - 1],則可以看到結過就不同了,但是都是最長公共子串行。

此處用到的演算法為動態規劃,理解這個演算法,需要仔細的看著演算法和**,好好想想,就會明白其中的奧妙。

using

system;  

using

system.collections.generic;  

using

system.linq;  

using

system.text;  

namespace

console.writeline();  

}  console.writeline();  

console.writeline();  

for(

inti = 0; i 

console.writeline();  

}  console.writeline(backtrack2(b, x, x.length, y.length));  

}  static

void

lcslength(

string

x, string

y, int

[,] c, 

char

[,] b)  

else

//如果當前元素不相等,分2種情況計算公共子串行的長度

else

}  }  }  

}  static

string

backtrack1(

int[,] c, 

string

x, string

y, int

i, int

j)  

static

string

backtrack2(

char

[,] b, 

string

x, int

i, int

j)  

}  } 

最長公共子串行 動態規劃

經常會遇到複雜問題不能簡單地分解成幾個子問題,而會分解出一系列的子問題。簡單地採用把大問題分解成子問題,並綜合子問題的解匯出大問題的解的方法,問題求解耗時會按問題規模呈冪級數增加。為了節約重複求相同子問題的時間,引入乙個陣列,不管它們是否對最終解有用,把所有子問題的解存於該陣列中,這就是動態規劃法所...

最長公共子串行 動態規劃

關於用動態規劃法求兩個序列的最長公共子串行問題的相關知識見 王曉東 計算機演算法設計與分析 第三章。注意,這裡所指的最長公共子串行是可以不相鄰的,與平常所說的最長公共子串 相鄰的 不一樣。直接上 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 ...