程式設計之美 最長公共子串行 子串

2021-06-01 04:59:11 字數 1388 閱讀 3918

求最長公共子串有兩種情況:1,要求子串連續

。2,不要求子串連續 。

1.要求子串連續這種情況比較簡單

原理如下:設定乙個矩陣p,p[i][j]表示以str1[i]和str2[j]結尾的子串的最大公共子串的長度。利用如下遞推式求解:

如果 str1[i] != str2[j], p[i][j] = 0.

如果 str1[i]  = str2[j], p[i][j] = p[i-1][j-1] + 1.

2.要求子串不連續

這種情況的遞推式為:

如果 str1[i] != str2[j], p[i][j] = max(p[i-1][j],  p[i][j-1]).

如果 str1[i]  = str2[j], p[i][j] = p[i-1][j-1] + 1.

templateint common_cstr(const _ty *a , const _ty *b, int lena=0, int lenb=0,int continuous = 1)

int **poj = new int*[lena];

for(int i = 0; i < lena; i++)

int max = 0;

int max_i ,max_j;

/*******************************公共部分-建立矩陣結束*********************************************/

/**********子串求解****************/

if(continuous == 1) //要求子串連續的情況

if(poj[i][j] > max)//求解的過程中記錄一下最長子串的長度,以及結尾的下標 用於後面列印結果使用

}} else //子串不連續

else

if(poj[i][j] > max)//求解的過程中記錄一下最長子串的長度,以及結尾的下標 用於後面列印結果使用

}} /*****************找到子串起始位置*****************/

cout << "最長公共子串的長度為: " << max << endl;

cout << "公共子串的逆序為:" << endl;

if(continuous == 1)//連續的情況很簡單

} else

else

}} cout << endl;

for(int i = 0; i < lena; i++)

delete poj[i];

delete poj;

return max;

}

上述**列印的子串很可能不是唯一的,要全部找出來可以遍歷一下 poj矩陣找出所有最大值,然後根據相應的規則找出來

最長公共子串行 最長公共子串

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...