最長公共子串行 最長公共子串

2021-08-15 20:12:00 字數 1739 閱讀 2695

1.區別

找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。

2、最長公共子串

其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧:"bab"和"caba"(當然我們現在一眼就可以看出來最長公共子串是"ba"或"ab")

b  a  b

c  0  0  0

a  0  1  0

b  1  0  1

a  0  1  0

我們看矩陣的斜對角線最長的那個就能找出最長公共子串。

不過在二維矩陣上找最長的由1組成的斜對角線也是件麻煩費時的事,下面改進:當要在矩陣是填1時讓它等於其左上角元素加1。

b  a  b

c  0  0  0

a  0  1  0

b  1  0  2

a  0  2  0

這樣矩陣中的最大元素就是 最長公共子串的長度。

在構造這個二維矩陣的過程中由於得出矩陣的某一行後其上一行就沒用了,所以實際上在程式中可以用一維陣列來代替這個矩陣。

2.1 **如下:

public class lcstring2  else 

if (c[j] > max[0])

} else if (c[j] == max[0]) }}

}}for (j = 0; j < maxlen; j++) }}

public static void main(string args)

}

2.最長公共子串行

1)最長公共子串行的長度的動態規劃方程

設有字串a[0...n],b[0...m],下面就是遞推公式。字串a對應的是二維陣列num的行,字串b對應的是二維陣列num的列。

另外,採用二維陣列flag來記錄下標ij的走向。數字"1"表示,斜向下;數字"2"表示,水平向右;數字"3"表示,豎直向下。這樣便於以後的求解最長公共子串行。

(2)求解公共子串行**

#include#includechar a[500],b[500];

char num[501][501]; ///記錄中間結果的陣列

char flag[501][501]; ///標記陣列,用於標識下標的走向,構造出公共子串行

void lcs(); ///動態規劃求解

void getlcs(); ///採用倒推方式求最長公共子串行

int main()

void lcs()

else if(num[i][j-1]>num[i-1][j])

else}}

}void getlcs()

else if(flag[i][j]==2) ///如果是斜向右標記

j--;

else if(flag[i][j]==3) ///如果是斜向下標記

i--;

}for(i=k-1;i>=0;i--)

printf("%c",res[i]);

}

(3)圖示

最長公共子串行 最長公共子串

1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...

最長公共子串 最長公共子串行

子串要求連續 子串行不要求連續 之前的做法是dp求子序列 include include include using namespace std const int inf 0x3f3f3f3f const int mod 1000000007 string s1,s2 int dp 1010 10...

最長公共子串行 最長公共子串

最長公共子串行 class solution for int i 0 i len2 i for int i 1 i len1 i return result len1 len2 最長公共子串 class solution for int i 0 i len2 i for int i 1 i len1...