最長公共子串行問題。設有兩個字串行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的最長對角線就能找到最長公...