動態規劃 最長公共子串行(LCS)

2021-09-07 04:14:09 字數 1778 閱讀 7150

最長公共子串行也是動態規劃中的乙個經典問題。

有兩個字串 s1 和 s2,求乙個最長公共子串,即求字串 s3,它同時為 s1 和 s2 的子串,且要求它的長度最長,並確定這個長度。這個問題被我們稱為最長公共子串行問題。

與求最長遞增子串行一樣,我們首先將原問題分割成一些子問題,我們用 dp[i][j]表示 s1 中前 i 個字元與 s2 中前 j 個字元分別組成的兩個字首字串的最長公共子串長度。

顯然的,當 i、 j 較小時我們可以直接得出答案,如 dp[0][j]必等於 0。那麼,假設我們已經求得 dp[i][j](0<=i

相反的,若 s1[x] != s2[y],此時其最長 公共子串長度為 s1 中前 x-1 個字元和 s2 中前 y 個字元的最長公共子串長度與 s1 中前 x 個字元和 s2 中前 y-1 個字元的最長公共子串長度的較大者,即在兩種 情況下得到的最長公共子串都不會因為其中乙個字串又增加了乙個字元長度 發生改變。綜上所述, dp[x][y] = max。

最長公共子串行的遞推條件

假設有兩個字串s1和s2,其中s1的長度為n,s2的長度為m,用dp[i][j]表示s1前i個字元組成的字首子串與s2前j個字元組成的字首子串的最長公共子串長度,如下:

dp[0][j] = dp[i][0] = 0,其中j>=0 && j<=m,i>=0 && i<=n;

dp[i][j] = dp[i-1][j-1]+1;(s1[i] = s2[j])

dp[i][j] = max;(s1[i] != s2[j])

最後可以求得dp[n][m]中儲存的值即為兩個原始字串的最長公共子串行長度。

按照上面的公式可以寫出最長公共子串行的演算法

#include "

stdafx.h

"#include

#include

using

namespace

std;

#define maxsize 101

char

str1[maxsize];

char

str2[maxsize];

//'l'表示dp[i][j] = dp[i][j] = dp[i - 1][j];

//『q』表示dp[i][j] = dp[i][j] = dp[i - 1][j];

//'u'表示dp[i][j] = dp[i][j - 1];

char

path[maxsize][maxsize];

intdp[maxsize][maxsize];

void printlcs(int i, int

j)

else

if (path[i][j] == 'u'

) printlcs(i - 1

, j);

else

printlcs(i, j - 1

);

} int

main()

else

else}}

cout

<< dp[n][m] <

printlcs(n, m);

return0;

}

view code

測試例項:

str1 = 「abcbdab」;str2 = "bdcaba"。

輸出如下:

雖然str1和str2的最長公共子串行有多個,根據dp[n][m]進行遞迴輸出,只輸出乙個最長公共子串行。

最長公共子串行LCS(動態規劃)

1.描述 給定兩個序列 x y 求x和y的乙個最長公共子串行。2.分析 設最長子序列 z 則 1 若 xm yn 則 zk xm yn,且z k 1 是 x m 1 和 y n 1 的最長公共子串行 2 若 xm yn 且 zk xm 則 z 是 x m 1 和 y 的最長公共子串行 3 若 xm ...

最長公共子串行(LCS) 動態規劃

首先,動態規劃的關鍵是將之前所計算的結果儲存起來,之後直接呼叫!1.問題描述 字串的子串行 是指從該字串中去掉任意多個字元後剩下的字元在不改變順序的情況下組成的新字串。最長公共子串行 是指多個字串可具有的長度最大的公共的子串行。比如 adbcbd bdcaba這兩個字串的最長公共子串行是dcb 2....

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

動態規劃 最長公共子串行 lcs 題目描述 給定兩個字串 或數字序列 a和b,求乙個字串,使得這個字串是a和b的最長公共部分 子串行可以不連續 如樣例所示,字串 sadstory 與 adminsorry 的最長公共子串行為 adsory 長度為6 動態規劃的解法 令dp i j 表示字串a的i號位...