最大公共字串

2021-06-22 08:16:34 字數 1965 閱讀 7328

最簡單的方法就是依次比較,以某個串為母串,然後生成另乙個串的所有長度的子串,依次去母串中比較查詢,這裡可以採用先從最長的子串開始,減少比較次數,但是複雜度依然很高!

然後重新看一下這個問題,我們建立乙個比較矩陣來比較兩個字串str1和str2

定義lcs(i,j) ,當str1[i] = str2[j]時lcs(i,j)=1,否則等於0。

example:

str1 ="bab"

str2 ="caba"

建立矩陣

--b a  b

c 0 0  0

a 0 1  0

b 1 0  1

a 0 1  0

連續i子串的特點就是如果str1[i]和str2[j]是屬於某公共子串的最後乙個字元,那麼一定有str1[i]=str2[j]&& str1[i-1] =str2[j-1],從矩陣中直觀的看,就是由「1」構成的「斜線」代表的序列都是公共子串,那麼最長公共子串肯定就是斜線「1」最長的那個串。

那麼現在問題就可以轉化了,只要構造出如上的乙個矩陣,用n^2的時間就可以得到矩陣,然後再到矩陣中去尋找最長的那個「1」構成的斜線就可以了!那麼,現在又有了新的問題?如何快速的找到那個「1」構成的最長斜線呢?

採用dp的思想,如果str1[i]= str2[j],那麼此處的包含str1[i] 和str2[j]公共子串的長度必然是包含str1[i-1]和str2[j-1]的公共子串的長度加1,那麼現在我們可以重新定義lcs(i,j),即是lcs(i,j)= lcs(i-1,j-1) + 1,反之,lcs(i,j) = 0。那麼上面的矩陣就變成了如下的樣子:

--b a  b

c 0 0  0

a 0 1  0

b 1 0  2

a 0 2  0

現在問題又變簡單了,只需要花n^2的時間構造這樣乙個矩陣,再花n^2的時間去找到矩陣中最大的那個值,對應的就是最長公共子串的長度,而最大值對應的位置對應的字元,就是最長公共子串的最末字元。

演算法還可以改進,我們可以將查詢最大長度和對應字元的工作放在構造矩陣的過程中完成,一邊構造一邊記錄當前的最大長度和對應位置,這樣就節省了n^2的查詢時間。

空間上也可以做改進,如果按照如上的方式構造,我們發現,當矩陣的第i+1行的值計算完成後,第i行的值就沒有用了,即便是最長的長度出現在第i行,我們也已經用變數記錄下來了。因此,可以將矩陣縮減成乙個向量來處理,向量的當前值對應第i行,向量的下乙個迴圈後的值對應第i+1行。

//        最長公共子串(連續)        lcs

//        dengchao

//        2012.12.4

#include

#include

using namespace std;

//        查詢公共子串

//        lcs記錄公共子串

//        return        公共子串長度

int lcs(const char*str1  , int len1 , const char *str2 ,int len2 , char *&lcs)

//        壓縮後的最長子串記錄向量

int*c = new int[len2+1];

for(inti = 0 ; i < len2 ; ++i)

intmax_len = 0;        //匹配的長度

intpos =0;                //在str2上的匹配最末位置

for(inti = 0 ; i < len1 ; ++i)

}else}}

if(0== max_len)

//        得到公共子串

lcs= new char[max_len];

for(inti = 0 ; i < max_len ; ++i)

cout<<"pos= "returnmax_len;

}//        test

int main()

}

最大公共字串

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

最大公共字串

a i 1 j 1 1最大公共子串長度問題就是 求兩個串的所有子串中能夠匹配上的最大長度是多少。比如 abcdkkk 和 baabcdadabc 可以找到的最長的公共子串是 abcd 所以最大公共子串長度為4。下面的程式是採用矩陣法進行求解的,這對串的規模不大的情況還是比較有效的解法。請分析該解法的...

動態規劃 最大公共字串

問題定義 乙個字串s,去掉零個或者多個元素所剩下的子串稱為s的子串行。最長公共子串行就是尋找兩個給定序列的子串行,該子串行在兩個序列中以相同的順序出現,但是不必要是連續的。例如序列x abcbdab,y bdcaba。序列bca是x和y的乙個公共子串行,但是不是x和y的最長公共子串行,子串行bcba...