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

2021-08-14 01:17:08 字數 2076 閱讀 8308

問題描述

給定兩個字串,尋找這兩個字串之間的最長公共子串行。

輸入格式

輸入兩行,分別包含乙個字串,僅含有小寫字母。

輸出格式

最長公共子串行的長度。

樣例輸入

abcdgh

aedfhb

樣例輸出

3樣例說明

最長公共子串行為a,d,h。

資料規模和約定

字串長度1~1000。

分析:求最長公共子串行,用動態規劃~只需建立乙個長寬為兩個字串長度+1的二維陣列~dp[i][j]表示string a的前i個字元構成的字串和string b的前j個字元構成的字串這兩者得到的最長公共子串行的長度為dp[i][j]~~~所以第0行和第0列所有的數都為0~

根據遞推公式:

最後乙個格仔的長度就是兩個字串的最長公共子串行的長度~

#include using namespace std;  

int dp[1001][1001];

int main()

} cout << dp[a.length()][b.length()];

return 0;

}

這個解法只能解決求最長子序列長度的問題,並不能得到最長子序列。因此,可以改良一下:

一、問題描述

求兩個字串行的公共最長子序列。例如字串行abcbdb和字串行acbbabdbb的最長公共子串行為acbdb。

二、問題分析

(1)用l[i][j]表示子串行xi和yj的最長公共子串行的長度

,動態規劃函式為

l[i][j] = l[i - 1][j - 1] + 1,   xi等於yj

= max(l[i][j - 1], l[i - 1][j]

),    xi不等於yj

邊界條件第0行和第0列均為0,即l[i][0] = l[0][j] = 0

上例中l填寫情況如下

(2)因為不只要求出最大長度,還要尋找到公共最長子序列

,所以在填表l[i][j]過程中,再填乙個表s[i][j],

若xi等於yj,設定s[i][j] = 1;

若xi不等於yj,並且len[i + 1][j] >= len[i][j + 1],設定s[i][j] = 2; 若

xi不等於yj,並且

len[i + 1][j] < len[i][j + 1],設定

s[i][j] = 3;

填表s[i][j]完成後,具體如何找到最長公共子串行詳見**注釋。

上例中s填寫情況及尋找最長公共子串行過程如下

三、演算法**

public static void maxcommonchar(char  a, char  b)else if(len[i + 1][j] >= len[i][j + 1])else  

} }

int k = len[m][n]; //最長公共子串長度

char commonchars = new char[k];//儲存最長公共子串

int i = m, j = n; //從右下角的格仔出發

for(;i > 0 && j > 0;)else if(flags[i][j] == 2)else

} system.out.println("最長公共子串行長度為:" + len[m][n]);

system.out.print("最長公共子串行為:");

for(int l = 0; l <= len[m][n] - 1; l++)

}

最長公共子串行問題(動態規劃演算法)

問題 給出兩個字串a a1 a2a3 an和b b1 b2b3 bm,求a和b的最長公共子串行的長度。例如 a xyxxzxyzxy,b zxzyyzxxyxxz,則它們的最長公共子串行為xy z,長度為6。注意 最長公共子串行不一定要求連續的字串,只講究先後順序一致。約定 l i,j 表示這樣兩個...

動態規劃之最長公共子串行演算法

動態規劃之最長公共子串行演算法 演算法思想 假設x x1,x2,xm y static void init xy void getchar for i 1 i n i getchar static void lcs length void else if c i 1 j c i j 1 else p...

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

最長公共子串行簡介 舉例說明並分析 塊測試結果 乙個給定序列的子串行是在該序列中刪去若干元素後得到的序列,確切的說,若給定序列x 則另一串行z x的子串行是指存在乙個嚴格的下標序列,使得對於所有的j 0,1,k 1有zj xij。例如序列z 是序列x 的子串行,相應的遞增下標序列維。最長公共子串行問...