最長公共子串行是乙個很經典的動態規劃問題,最近正在學習動態規劃,所以拿來這裡再整理一下。
這個問題在《演算法導論》中作為講動態規劃演算法的例題出現。
動態規劃,眾所周知,第一步就是找子問題,也就是把乙個大的問題分解成子問題。這裡我們設兩個字串a、b,a = "a0, a1, a2, ..., am-1",b = "b0, b1, b2, ..., bn-1"。
(1)如果am-1 == bn-1,則當前最長公共子串行為"a0, a1, ..., am-2"與"b0, b1, ..., bn-2"的最長公共子串行與am-1的和。長度為"a0, a1, ..., am-2"與"b0, b1, ..., bn-2"的最長公共子串行的長度+1。
(2)如果am-1 != bn-1,則最長公共子串行為max("a0, a1, ..., am-2"與"b0, b1, ..., bn-1"的公共子串行,"a0, a1, ..., am-1"與"b0, b1, ..., bn-2"的公共子串行)
如果上述描述用數學公式表示,則引入乙個二維陣列c,其中c[i][j]記錄x[i]與y[j]的lcs長度,b[i][j]記錄c[i][j]是通過哪乙個子問題的值求得的,即,搜尋方向。
這樣我們可以總結出該問題的遞迴形式表達:
按照動態規劃的思想,對問題的求解,其實就是對子問題自底向上的計算過程。這裡,計算c[i][j]時,c[i-1][j-1]、c[i-1][j]、c[i][j-1]已經計算出來了,這樣,我們可以根據x[i]與y[j]的取值,按照上面的遞推,求出c[i][j],同時把路徑記錄在b[i][j]中(路徑只有3中方向:左上、左、上,如下圖)。
計算c矩陣的時間複雜度是o(m*n);根據b矩陣尋找最長公共子串行的過程,由於每次呼叫至少向上或向左移動一步,這樣最多需要(m+n)次就會i = 0或j = 0,也就是演算法時間複雜度為o(m+n)。
一下是**實現:
1 #include 2 #include 3 #includeview code4 #include 56
using
namespace
std;78
void lcs_print(int **lcs_direction, char *str, int row, int
column)924
else
if(lcs_direction[row][column] == 2)25
29else
if(lcs_direction[row][column] == 3)30
34}3536
int lcs(char *str1, char *str2)
3756
57for(int i = 0; i < nlen1; i++)
58 lcs_length[i][0] = 0;59
for(int i = 0; i < nlen2; i++)
60 lcs_length[0][i] = 0;61
62for(int i = 0; i < nlen1; i++)
6368}69
70 cout<
init ok!
"<
7172
for(int i = 0; i )
7383
else
84 lcs_length[i][j] = 0;85
}86else
if(str1[i] ==str2[j])
8791
else
if(lcs_length[i - 1][j] > lcs_length[i][j - 1
])92
96else
97101
}102
}103
104 lcs_print(lcs_direction, str1, nlen1 - 1, nlen2 - 1
);105 cout<
106int nlcs = lcs_length[nlen1 - 1][nlen2 - 1
];107
for(int i = 0; i < nlen1; i++)
108112
delete lcs_length;
113delete lcs_direction;
114return
nlcs;
115}
116117
intmain()
118
跟著程式設計之美學演算法 最長公共子串行
最長公共子串行是乙個很經典的動態規劃問題,最近正在學習動態規劃,所以拿來這裡再整理一下。這個問題在 演算法導論 中作為講動態規劃演算法的例題出現。動態規劃,眾所周知,第一步就是找子問題,也就是把乙個大的問題分解成子問題。這裡我們設兩個字串a b,a a0,a1,a2,am 1 b b0,b1,b2,...
程式設計之美 最長公共子串行 子串
求最長公共子串有兩種情況 1,要求子串連續 2,不要求子串連續 1.要求子串連續這種情況比較簡單 原理如下 設定乙個矩陣p,p i j 表示以str1 i 和str2 j 結尾的子串的最大公共子串的長度。利用如下遞推式求解 如果 str1 i str2 j p i j 0.如果 str1 i str...
最長公共子串行 最長公共子串
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...