兩字串最長公共子串行 動態規劃連續和非連續

2021-08-22 19:38:20 字數 2483 閱讀 4951

史上最全最豐富的「最長公共子串行」、「最長公共子串」問題的解法與思路

非連續的最長公共子串行

求兩個字串的最長公共子串行。借用演算法導論上的表示方法,給定乙個字串x=(下劃線後面的數字表示下標),另乙個字串y=,求x和y的最長公共子串行。同時我們用x_i表示x中前i個字元構成的字串x_i = ,用y_j表示y紅前j個字元構成的字串y_j = 。

現在就想怎麼把問題變為為小問題呢?怎麼解決這個問題呢?

關鍵要找到問題的突破口,先不要管最終解決,先想一想怎麼吧問題花姐的規模小一些。我先分別拿兩個字串的最後乙個字元「開刀」,先拿他們比較

1)我們可以首先比較x_m和y_n如果這兩個字元相同,那麼x_m = y_n一定是最長公共子串行中的乙個字元。那麼我們的問題就是求x_(m-1) = 和y_(n-1) = 的最長公共子串行了。如果能求出x_(m-1)和y_(n-1)的最長公共子串行,這個子串行在加上字元x_m = y_n就是我們所求問題的最長公共子串行了。

2)如果x_m != y_n,我們要求x和y的最長公共最序列,就轉為求兩個子問題,乙個是求x_m和y_(n-1)的最長公共子串行,另乙個是求x_(m-1)和y_n的最長公共子串行。取兩者中最長的那個就是問題的解。

至此,大問題就化為小問題的,具體我們可以寫遞推公式。

假如用c[i,j]表示x_i和y_j序列的最大公共子串行的長度的話

c[i,j] = 0 如果i == 0或者j == 0

c[i,j] = c[i - 1][j - 1] 如果x_j == y_j

c[i,j] = max(c[i-1,j], c[i, j-1]) 如果x_i != y_j

有了遞推公式,定義對應遞推公式的陣列,就可以求得最終的答案。

#include#include#includeusing namespace std;

int max(const int& a, const int& b)

//模板函式用來輸出二維陣列

templatevoid print_vector(const vector>& vec)

cout << endl; }}

//getlcs函式用來求兩個字串的最大公共子串行,並返回其長度

int getlcs(const string& str1, const string& str2)

size_t len1 = str1.size();

size_t len2 = str2.size();

//lcs用來儲存兩字串str1[0,...,row]和str1[0,...,col]的最長公共序列的長度

vector> lcs(len1 + 1, vector(len2 + 1, 0));

//index用來儲存如何找到最長公共子串行

vector> index(len1 + 1, vector(len2 + 1, '-'));

for(size_t row = 0; row != len1 + 1; row++)

if(str1[row - 1] == str2[col - 1])

if(str1[row - 1] != str2[col - 1])

else

}} }

cout << "lcs vector is " << endl;

print_vector(lcs);

cout << "index vector is " << endl;

print_vector(index);

return lcs[len1][len2];}

int main(void)

兩個字串最長連續公共序列

如下兩個字串,公共連續字串為abcdf,求出這個abcdf,

"aaffffsfabcdfasf", "aaaadfsabcdfsdb"

假設字串長度分別為m,n,這個題有個m*n*min(m,n)複雜度的方法,這個方法比較慢,暫時不考慮。

另乙個種方法是動態規劃:

設定二維陣列dp, dp[i][j]==0表示第乙個字串的第i個字元與第二個字串的第j個字元不相等,dp[i][j]!=0表示第乙個字串的第i個字元與第二個字串的第j個字串相等,並且,如果dp[i][j]==k,不僅當前字元相等,前面k-1個也相等,也就是dp的公式為dp[i][j] = dp[i-1][j-1]+1。最終二維矩陣的結果如下所示(隨機寫的):

**如下:

//求兩個字串的最大公共字串

public string longestserialsubstring(string s1,string s2)}}

} res = s1.substring(index-max+1,index+1);

return res;

}

兩字串最長公共子串行 動態規劃

首先碰到求兩字串最長公共連續子串的問題,然後想到原先做過的求兩字串最長公共子串行問題,所以又把演算法導論上的解法看了一下。這兩個問題是不同的問題,求最長公共子串行不要求求得的子字串時連續的,比如說acb和ab的最長公共子串行就是ab。而最長公共連續子串,要求求得的子串在兩個字串中必須是連續出現的,還...

最長公共子串行 動態規劃

經常會遇到複雜問題不能簡單地分解成幾個子問題,而會分解出一系列的子問題。簡單地採用把大問題分解成子問題,並綜合子問題的解匯出大問題的解的方法,問題求解耗時會按問題規模呈冪級數增加。為了節約重複求相同子問題的時間,引入乙個陣列,不管它們是否對最終解有用,把所有子問題的解存於該陣列中,這就是動態規劃法所...

最長公共子串行 動態規劃

關於用動態規劃法求兩個序列的最長公共子串行問題的相關知識見 王曉東 計算機演算法設計與分析 第三章。注意,這裡所指的最長公共子串行是可以不相鄰的,與平常所說的最長公共子串 相鄰的 不一樣。直接上 lcs.h ifndef lcs h define lcs h class lcstring endif...