求最長公共子串行

2021-07-06 11:18:25 字數 1565 閱讀 7886

問題:

求兩字串行的最長公共字元子串行。

(這裡注意子串行和子串的區別,子串行可以是從原字串中取出一部分元素重新拼接而成的字串,但取出的元素之間的前後關係要與原字串一致;而子串則必須是連續的。如」adf」是」abcdef」的子串行,而不是子串。)

分析與解法:

設序列x=和y=的最長公共子串行為z= ,則

若xm-1=yn-1,則zk-1=xm-1=yn-1,且是和的最長公共子串行。

若xm-1≠yn-1且zk-1≠xm-1,則 是和最長公共子串行。

若xm-1≠yn-1且zk-1≠yn-1,則是和的最長公共子串行。

使用動態規劃的方法,將問題分為兩個子問題。

引進二維陣列c和b,用c[i][j]記錄x[i]與y[j] 的最長子序列的長度,b[i][j]記錄c[i][j]是通過哪乙個子問題的值求得的,以決定搜尋的方向。最後還要用回溯的方法把最長子串輸出出來。

遞推公式如下,

**如下,

#include

#define maxsize 50

using

namespace

std;

/*計算字串的最長子序列的長度*/

void lcs(char *x, char *y, int x_len, int y_len, int c[maxsize], int b[maxsize])

else

if(c[i][j - 1] <= c[i - 1][j])

else}}

}/*輸出最長子序列*/

void showlcs(int i, int j, int b[maxsize], char *x)

else

if(b[i][j] == -1)

showlcs(i - 1, j, b, x);

else

showlcs(i, j - 1, b, x);

}/*測試*/

int main(void)

借助圖表理解搜尋和輸出方式,

「左上」對應」i-1, j-1」,記作」0」

「上」對應」i-1, j」,記作」-1」

「左」對應」i, j-1」,記作」1」

求最長公共子串行的時間複雜度是o(mn)

由於每次呼叫至少向上或向左(或向上向左同時)移動一步,故最多呼叫(m + n)次就會遇到i = 0或j = 0的情況,此時開始返回。返回時與遞迴呼叫時方向相反,步數相同,故回溯列印最長公共子串行的時間複雜度是o(m+n)

文章參考以下博文:

求最長公共子串行

字串行的子串行是指從給定字串行中隨意地 不一定連續 去掉若干個字元 可能乙個也不去掉 後所形成的字串行。令給定的字串行 x x0,x1,xm 1 序列 y y0,y1,yk 1 是 x 的子串行,存在 x的乙個嚴格遞增下標序列 i1,ik 1 使得對所有的 j 0,1,k 1 有 xij yj 例如...

求最長公共子串行和最長公共子串

輸入描述 輸入為兩行字串 可能包含空格 長度均小於等於50。輸出描述 輸出為乙個整數,表示最長公共連續子串的長度。輸入例子 abcde abgde 輸出例子 2題解 例如 str1 abcde str2 abgde matrix 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0...

求最長公共子串行本身

題目詳情請見 求字串的最長公共子串行 在上題求出子串行長度基礎上,我們要求出子串行本身長什麼樣 思路 在求最大長度的時候,我把當前最大長度的 記下來,用path陣列儲存 1 當前string1 i string2 j 2 當前string i string2 j 並且dp i 1 j dp i j ...