想要了解最長公共子串行首先要清楚這些概念:
<1>子串行:就是在原序列中找出一部分組成的序列。 例:字串「abcdefg」 的子串行有 「ac」、「ade」....一共有27個子序列
<2>最長公共子串行:乙個序列 s ,如果分別是兩個或多個已知序列的子串行,且是所有符合此條件序列中最長的,則 s 稱為已知序列的最長公共子串行。
例:字串「cnblogs」和「belong」的最長公共子串行為「blog」。
仔細想想我們可以發現其實最長公共子串行的個數不是唯一的,可能會有兩個以上,
但是長度一定是唯一的,比如這裡的最長公共子串行的長度為4。
<3>子串:串中任意個連續的字元組成的子串行稱為該串的子串
<4>最長公共子串:兩個字串中,最長的相同子字串的長度
最長公共子串(longest common substirng)和最長公共子串行(longest common subsequence,lcs)的區別為:
子串是串的乙個連續的部分,子串行則是從不改變序列的順序,而從序列中去掉任意的元素而獲得新的序列;
也就是說,子串中字元的位置必須是連續的,子串行則可以不必連續。
最長公共子串行的應用:最長公共子串行是乙個十分實用的問題,它可以描述兩段文字之間的「相似度」,
即它們的雷同程度,從而能夠用來辨別抄襲。對一段文字進行修改之後,
計算改動前後文字的最長公共子串行,將除此子串行外的部分提取出來,
解決最長公共子串行問題 最好的選擇 ---> 「動態規劃」
動態規劃的計算兩個序列的最長公共子串行的方法如下:
以兩個序列 s1、s2 為例子:
設有二維陣列x[i,j] 表示 s1 的 i 位和 s2 的 j 位之前的最長公共子串行的長度,則有:
x[1][1] = same(1,1);
x[i,j] = max
其中,same(a,b)當 x 的第 a 位與 y 的第 b 位相同時為「1」,否則為「0」。
此時,二維陣列中最大的數便是 s1 和 s2 的最長公共子串行的長度,依據該陣列回溯,便可找出最長公共子串行。
該演算法的空間、時間複雜度均為o(n^2),經過優化後,空間複雜度可為o(n)。
1 #include 2 #include 34char s1[1000],s2[1000];5
int x[1000][1000]; //
記錄最長公共子串行
6int y[1000][1000]; //
記錄路徑
7int
lcs() 824
else
if(x[i-1][j] >= x[i][j-1]) //
不相等的時候選擇 比較「左邊」和「上邊」選擇較大的
2529
else
3034}35
}36return
x[l1][l2];37}
38void print_lcs(int i,int j) //
根據標記路徑的陣列 輸出最長公共子串行
3947
else
if (y[i][j] == 2) //
左邊 48 print_lcs(i-1
,j);
49else
//上邊
50 print_lcs(i,j-1
);51 }
最長公共子串行 最長公共子串
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...