題:給定兩個字串x,y,求二者最長的公共子串,例如x=[aaaba],y=[abaa]。二者的最長公共子串為[aba],長度為3。
1 基本演算法
其實對於最長公共子串,還是比較簡單易想的,因為子串是連續的,這就方便了很多。
最直接的方法就是用x每個子串與y的每個子串做對比,求出最長的公共子串。
2 dp方案
既然最長公共子串是最長公共子串行的變體,那麼最長公共子串是不是也可以用動態規劃來求解呢?
我們還是像之前一樣「從後向前」考慮是否能分解這個問題,在最大子陣列和中,
我們也說過,對於陣列問題,可以考慮「如何將arr[0,...i]的問題轉為求解arr[0,...i-1]的問題」,
類似最長公共子串行的分析,這裡,我們使用dp[i][j]表示 以x[i]和y[j]結尾的最長公共子串的長度,
因為要求子串連續,所以對於x[i]與y[j]來講,它們要麼與之前的公共子串構成新的公共子串;要麼就是不構成公共子串。
故狀態轉移方程
x[i] == y[j],dp[i][j] = dp[i-1][j-1] + 1
x[i] != y[j],dp[i][j] = 0
對於初始化,i==0或者j==0,如果x[i] == y[j],dp[i][j] = 1;否則dp[i][j] = 0。
#include#includevoid outputlcs(char * x);
// 最長公共子串 longest common substring
int maxlen; //記錄最大公共子串長度
int maxindex; // 記錄最大公共子串在串1的起始位置
void outputlcs(char * x); // 輸出lcs
// 最長公共子串 基本演算法 ***************====
int comlen(char * p, char * q)
return len;}
void lcs_base(char * x, int xlen, char * y, int ylen)}}
outputlcs(x);
}// 最長公共子串 dp ***********************************===
int dp[30][30];
void lcs_dp(char * x, int xlen, char * y, int ylen)
if(i == 0 || j == 0)
if(dp[i][j] > maxlen)}}
}outputlcs(x);
}//**********== common code *************************====
void outputlcs(char * x)
printf("the len of lcs is %d\n",maxlen);
int i = maxindex;
while(maxlen--)
printf("\n");}
void main()
最長公共子串行 最長公共子串
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...
最長公共子串行 最長公共子串
1.區別 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。2 最長公共子串 其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公...
最長公共子串 最長公共子串行
子串要求連續 子串行不要求連續 之前的做法是dp求子序列 include include include using namespace std const int inf 0x3f3f3f3f const int mod 1000000007 string s1,s2 int dp 1010 10...