動態規劃法如何來解決最長公共子串行問題

2021-10-08 03:19:16 字數 2079 閱讀 8875

最長公共子串行問題。設有兩個字串行x和y,它們的元素分別存放在陣列x[m+1]和y[n+1]中,x[0]和y[0]不放元素。公共子串行存放在陣列z中。完成如下函式。

2、int commonorder(int m,int n,char x,char y,char z)函式功能是返回兩字串行的最長公共子串行長度值。並且公共子串行存放在陣列z中。

3、寫主函式main(),實現輸入陣列x和y,呼叫 commonorder函式,並輸出公共子串行。

(1)解題思路:引進乙個二維陣列c,用c[i][j]記錄x[i]與y[j] 的 最長公共子串行的長度,b[i][j]記錄c[i][j]是通過哪乙個子問題的值求得的,以決定搜尋的方向。我是自底向上進行遞推計算,那麼在計算c[i,j]之前,c[i-1][j-1],c[i-1][j]與c[i][j-1]均已計算出來。此時我根據x[i] = y[j]還是x[i] != y[j],就可以計算出c[i][j]。

(2)問題的遞迴式寫成:

(3)演算法分析:

由於動態規劃法,其中乙個for迴圈的時間效能為o(n * m),是所有迴圈的最大值,故演算法時間複雜度為o(m * n)。

(4)**如下:

#include

#include

int c[

200]

[200];

//用c[i][j]記錄x[i]與y[j] 的lcs 的長度

int b[

200]

[200];

//b[i][j]記錄c[i][j]是通過哪乙個子問題的值求得的,以決定搜尋的方向

intmax

(int m,

int n,

int i,

int j)

else

}/*遞迴列印z的元素內容*/

void

print

(int i,

int j,

int s,

char x,

char y,

char z)

else

if(b[i]

[j]==-1

)else

if(b[i]

[j]==1)

}int

commonorder

(int m,

int n,

char x,

char y,

char z)

else}}

//列印x和y的lcs

printf

("x和y的公共子串行z是:");

print

(m,n,c[m]

[n],x,y,z)

;printf

("%s"

,z);

printf

("\n");

return c[m]

[n];

}int

main()

printf

("請輸入字串y:");

scanf

("%s"

,y);

while

(strlen

(y)>

200)

s =commonorder

(m,n,x,y,z)

;printf

("x和y的公共子串行長度: %d \n"

,s);

}

(5)測試資料和執行結果

三、分析和經驗:

關於最長公共子串行問題,分為三種情況,一是若xm=yn,zk=xm=yn,所以zk-1是xm-1和yn-1的最長公共子串行;二是若xm不等於yn,zk不等於xm,所以zk是xm-1和yn的最長公共子串行;三是若xm不等於yn,zk不等於yn,所以zk是xm和yn-1的最長公共子串行。然後定義子問題,比較子串行,計算搜尋狀態,確定搜尋方向,動態規劃的求出原文問題的解,求出兩個序列的最長公共子串行。

最長公共子串行問題 動態規劃法

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

動態規劃解決最長公共子串行和最長公共子串

找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而找兩個字串的最長公共子串行,只要求子串行的字元都在原字串中出現且保持相對順序不對 動態規劃 1.最長公共子串,s1 a1a 2a3.am s2 b 1b2b 3.b n 狀態轉移方程 記f i,j 是以a i 和 b j 結尾的字 符串的最...

最長公共子串 最長公共子串 動態規劃

有兩個字串 可能包含空格 請找出其中最長的公共連續子串,輸出其長度。長度在1000以內 例如 輸入 abcde bcd 輸出 3 1 把兩個字串分別以行和列組成乙個二維矩陣。2 比較二維矩陣中每個點對應行列字元中否相等,相等的話值設定為1,否則設定為0。3 通過查詢出值為1的最長對角線就能找到最長公...