問題定義
乙個字串s,去掉零個或者多個元素所剩下的子串稱為s的子串行。
最長公共子串行就是尋找兩個給定序列的子串行,
該子串行在兩個序列中以相同的順序出現,但是不必要是連續的。
例如序列x=abcbdab,y=bdcaba。
序列bca是x和y的乙個公共子串行,但是不是x和y的最長公共子串行,
子串行bcba是x和y的乙個lcs,序列bdab也是。
尋找lcs的一種方法是列舉x所有的子串行,
然後注意檢查是否是y的子串行,並隨時記錄發現的最長子序列。
假設x有m個元素,則x有2^m個子序列,指數級的時間,對長序列不實際。
動態規劃思路
假設dp[i][j]是字串x、y的前i個字元和前j個字元的最長公共子串長度,則有:
1. dp[i][j] = 1+ dp[i-1][j-1]if(x[i-1] == y[j-1])
2. dp[i][j] = maxif(x[i-1] ≠ y[j-1])
邊界條件
dp[i][j] = 0(if i==0 || j==0)
#include
#include
using
namespace
std;
int max(int a, int b)
int dp(int** dp,const
char *x,const
char* y, int nxlength, int nylength)
if (x[i-1] == x[j-1])
else}}
return dp[nxlength][nylength];
}int main()
int lcslength = dp(dptable, x, y, nxlength, nylength);
cout
<<"最長公共子串長度為 "
<< lcslength << endl;
int i = 0;
int j = nxlength;
int k = nylength ;
char *strlcs = new
char[lcslength+1]; //根據儲存的狀態表,列印出最大公共子串
strlcs[lcslength] = '\0'; //由於是逆序尋找的,這裡通過將字元逆序插入strlcs中,最後順序列印
while (i < lcslength)
else
else}}
cout
<< strlcs << endl;
system("pause");
for (int i = 0; i < nxlength + 1; i++)
delete dptable;
delete strlcs;
return
0;}
最大公共字串
簡單dp問題 設兩個字串s1,s2,假設dp i j 代表到s1的第i個字元及s2的第j個字元時,最大公共字串的數目 那麼 if s1 i s2 j dp i j d i 1 j 1 1 else dp i j 0 如下 dp二維陣列空間是可以優化的,可以變成一位陣列.dp是個二維矩陣,舉例如下 a...
最大公共字串
最簡單的方法就是依次比較,以某個串為母串,然後生成另乙個串的所有長度的子串,依次去母串中比較查詢,這裡可以採用先從最長的子串開始,減少比較次數,但是複雜度依然很高!然後重新看一下這個問題,我們建立乙個比較矩陣來比較兩個字串str1和str2 定義lcs i,j 當str1 i str2 j 時lcs...
最大公共字串
a i 1 j 1 1最大公共子串長度問題就是 求兩個串的所有子串中能夠匹配上的最大長度是多少。比如 abcdkkk 和 baabcdadabc 可以找到的最長的公共子串是 abcd 所以最大公共子串長度為4。下面的程式是採用矩陣法進行求解的,這對串的規模不大的情況還是比較有效的解法。請分析該解法的...