動態規劃之最長子串匹配問題

2022-09-12 11:27:16 字數 3066 閱讀 8561

1.問題引出

最長字段匹配問題歸結如下:

假設存在兩個字元段:

a=;b= ;

則a、b兩個欄位的匹配即為a、b的公共子串行,如、、、均為該兩個字元段的公共子串行,而最長公共子串行則為以上子串行中長度最長的。如,長度為4。

2.問題求解

2.1動態規劃的簡述

動態規劃:把多階段過程轉化為一系列單階段問題,利用各階段之間的關係,逐個求解。通俗的解釋就是將乙個很大的問題轉化為乙個乙個很小的相關聯且可求解的子問題,每個子問題都可以被解決,並將結果儲存,下乙個子問題通過查詢上乙個子問題的結果進行求解,以此,只到最終問題被解決,這是一種以空間換取執行效率的方法。舉例:如計算2+3,如果用動態規劃的思想的話可將其分割為求1+1,1+2,2+3三個子問題,求出1+1的結果儲存,求出1+2的結果儲存,通過查詢利用前兩個子問題的結果得到2+3,算出最終結果。

2.2最長公共子串行的動態規劃描述

對於上面兩個子串行

a=;b= ;

設兩字元段的最長公共子串行result[i][j] (i為字元段a的長度,j為字元段b的長度),

①當a[i]=b[j]時,表示該問題可規劃為先找到a[i-1]與b[j-1]公共子串行值result[i-1][j-1],result[i][j] = result[i-1][j-1]+1. 定義序列型別trace[i][j] = 1,便於後期追蹤。

②當result[i-1][j] >= result[i][j-1]時,表示長度為i-1欄位a與長度為j的字段 b的公共子串行,大於等於長度為i欄位a與長度為j-1的字段 b,因此result[i][j] = result[i-1][j]; trace[i][j] = 2。

③當result[i-1][j] < result[i][j-1]時,表示長度為i-1欄位a與長度為j的字段 b的公共子串行,小於長度為i欄位a與長度為j-1的字段 b,此時result[i][j] = result[i][j-1];trace[i][j] = 3。

2.3**實現

#include #include 

#include /**

* 最長公共子串行求解演算法

* * @param lengths1 第乙個序列的長度

* @param lengths2 第二個序列的長度

* @param s1 第乙個序列頭指標

* @param s2 第二個序列頭指標

* @param result 最長公共子串行遞推求解結果矩陣,m+1行,n+1列

* @param trace 最長公共子串行追蹤矩陣,m+1行,n+1列

*/int lcslength(int lengths1, int lengths2, char* s1, char* s2, int** result, int**trace)

else

if(result[i-1][j] >= result[i][j-1])

else }}

return

result[lengths1][lengths2];}/*

** 最長公共子串行追蹤構造演算法

* @param tails1 第乙個序列尾部位置

* @param tails2 第二個序列的尾部位置

* @param s1 第乙個序列頭指標,根據追蹤矩陣在其中搜尋公共子串行中字元

* @param trace 追蹤矩陣

*/void lcstraceback(int tails1, int tails2, char* s1, int**trace)

else

if (trace[tails1][tails2] == 2)

else lcstraceback(tails1, tails2-1

, s1, trace);

}int

main();

char sequence2[lengths2] = ;

char* s1 =sequence1;

char* s2 =sequence2;

cout

<< "

s1:

"<< *s1;

for(i=1; i)

cout

<< "

"<< *(s1 +i);

cout

<

cout

<< "

s2:

"<< *s2;

for(i=1; i)

cout

<< "

"<< *(s2 +i);

cout

<

int** resultmatrix = new

int* [lengths1+1];//

m+1行n+1列迭代結果矩陣

for(i=0; i1; i++)

*(resultmatrix+i) = new

int [lengths2+1

];

int** tracematrix = new

int* [lengths1+1];//

m+1行n+1列追蹤矩陣

for(i=0; i1; i++)

*(tracematrix+i) = new

int [lengths2+1

]; cout

<< "

the length of the longest common sequence is:

"<< lcslength(lengths1, lengths2, s1, s2, resultmatrix, tracematrix) <

cout

<< "

the longest common sequece is:

"<

lcstraceback(lengths1, lengths2, s1, tracematrix);

return0;

}

view code

動態規劃之最長回文串

dp i j 表示 以s i 開始s j 結尾的回文串的長度。如果這個字串不是回文串,讓dp i j 0 顯然,j i,只需往dp填j i的部分即可。dp i j 的遞推公式可以這麼表述 1 首先對dp的對角線元素初始化為1,也就是當i j時,dp i j 1。這很顯然,每個單獨的字元其實就是個長度...

動態規劃 最長子序列問題

最長公共子串行 x和y的公共子串行中長度最長的 包含元素最多的 叫做x和y的最長公共子串行。思路 設x x1x2 xm和y y1y2 yn是兩個序列,z z1z2 zk是這兩個序列的乙個最長公共子串行。1.如果xm yn,那麼zk xm yn,且zk 1是xm 1,yn 1的乙個最長公共子串行 2....

動態規劃之最長回文子串

問題 給出乙個字串s,求s的最長回文子串的長度。樣例 字串 patzjujztaccbcc 的最長回文子串為 atzjujzta 長度為9。還是先看暴力解法 列舉子串的兩個端點i和j,判斷在 i,j 區間內的子串是否回文。從複雜度上來看,列舉端點需要0 n2 判斷回文需要0 n 因此總複雜度是o n...