詳細描述求最長公共子串行演算法

2021-07-05 06:21:29 字數 1833 閱讀 4014

子串行與字串的區別:

子串行不要求公共部分在原字串中連續,而字串要求連續。

動態規劃求解

例子:"bdcaba", "abcbdab"  最長的公共子串行為 b c b a 和 b d a b

1:首先分析狀態轉移陣列dp[i][j]的含義:

指的是 字串 s1 從 0到n-1 和 字串 s2 從 0到m-1 的最大公共子串行的長度。

如上面 dp[0][0]=0 因為 s1的「b」 和s2的'a"不相等,所以最大

公共子串行的長度為0

dp[0][1]=1

因為 s1的「b」 和s2的'ab"有乙個字母相等,所以

最大公共子串行的長度為1

以此類推以此計算 到 dp[0][m-1],再計算dp[1][0]到dp[1][m-1].......到dp[n-1][m-1]。

2:計算過程

(1)計算dp[i][j]時,先比較s1.charat(i)是否等於s2.charat(j),如果等於,就把dp[i][j]的長度置為dp[i-1][j-1]+1,為什麼是dp[i-1][j-1]+1

呢?因為當你的當前位置(i ,j)的對應字母相等時,最大長度就是上一次的最大長度加1,而上一次的最大長度就是dp[i-1][j-1]。比如:

當比較到 dp[2][2]時,即 字串 s1 「bdc」

和 字串 s2 "abc"

的最大公共子串行的長度。因為s1.charat(i)等於s2.charat(j),所以最大長度要在上一次的最大長度上加一,而上一次指的就是「bd」和"ab"也就是i-1和j-1。

(2)如果不相等,那就要判斷是少乙個i的長度大些呢,還是少乙個j的長度大些呢,也就是判斷dp[i-1][j]和dp[i][j-1]哪個大,找出大的放進dp[i][j]。

(3)最大長度肯定是dp[n-1][m-1]。因為這是完整的兩個串的最大子串行長度。

3:輸出

(1)因為dp陣列最後乙個是最大的長度,所以就從最後乙個開始回溯。

(2)比較s1.char

at(i)是否等於s2.charat

(j),如果等於就是輸出該字母。

(3)不等於就判斷dp[i-1][j]和dp[i][j-1]哪個大,如果dp[i-1][j]大,就到他的位置,也就是j不變,i-1;否則就相反。

(4)重複(2)(3)直到i<=1&&j<=1

4: 上面的思路用圖表達就是把s1和s2弄成乙個二維表

} system.out.println("最長最序列長度:"+dp[s1.length()][s2.length()]);

for (int i = 0; i < dp.length; i++)

system.out.println();

} system.out.println("-------輸出-------------");

int temps1 = s1.length();

int temps2 = s2.length();

while(temps1>=1 && temps2>=1)elseelse

}} return dp;

}

求最長公共子串行

問題 求兩字串行的最長公共字元子串行。這裡注意子串行和子串的區別,子串行可以是從原字串中取出一部分元素重新拼接而成的字串,但取出的元素之間的前後關係要與原字串一致 而子串則必須是連續的。如 adf 是 abcdef 的子串行,而不是子串。分析與解法 設序列x 和y 的最長公共子串行為z 則 若xm ...

求最長公共子串行

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

最長公共子串行演算法(LCS)及最長公共子串求法

最長公共子串行演算法c 實現 string lcs string s1,string s2 int m s1.length 1 int n s2.length 1 動態二維陣列的定義方法 int lcs new int m for int i 0 i m i for int i 0 i m i 生成...