一、什麼是最長公共子串行
什麼是最長公共子串行呢?舉個簡單的例子吧,乙個數列s,若分別是兩個或多個已知序列的子串行,且是所有符合條件序列中最長的,則s稱為已知序列的最長公共子串行。
舉例如下,如:有兩個隨機數列,1 2 3 4 5 6 和 3 4 5 8 9,則它們的最長公共子串行便是:3 4 5。
一直不明白:最長公共子串和最長公共子串行的區別。
上網查了下,最長公共子串(longest common substirng)和最長公共子串行(longest common subsequence,lcs)的區別為:子串是串的乙個連續的部分,子串行則是從不改變序列的順序,而從序列中去掉任意的元素而獲得新的序列;也就是說,子串中字元的位置必須是連續的,子串行則可以不必連續。
二、蠻力法
蠻力法是解決最長公共子串行問題最容易想到的方法,即對s的每乙個子串行,檢查是否為t的子串行,從而確定它是否為s和t的公共子串行,並且選出最長的公共子串行。
s和t的所有子串行都檢查過後即可求出s和t的最長公共子串行。s的乙個子串行相應於下標序列1,2,...,n的乙個子串行。因此,s共有2^n個子序列。當然,t也有2^m個子序列。
因此,蠻力法的時間複雜度為o(2^n * 2^m),這可是指數級別的啊。
三、動態規劃方法
1、序列str1和序列str2
·長度分別為m和n;
·建立1個二維陣列l[m.n];
·初始化l陣列內容為0
·m和n分別從0開始,m++,n++迴圈:
- 如果str1[m] == str2[n],則l[m,n] = l[m - 1, n -1] + 1;
- 如果str1[m] != str2[n],則l[m,n] = max
·最後從l[m,n]中的數字一定是最大的,且這個數字就是最長公共子串行的長度
·從陣列l中找出乙個最長的公共子串行
2、從陣列l中查詢乙個最長的公共子串行
i和j分別從m,n開始,遞減迴圈直到i = 0,j = 0。其中,m和n分別為兩個串的長度。
·如果str1[i] == str2[j],則將str[i]字元插入到子串行內,i--,j--;
·如果str1[i] != str[j],則比較l[i,j-1]與l[i-1,j],l[i,j-1]大,則j--,否則i--;(如果相等,則任選乙個)
圖1 效果演示圖
根據上圖,我們可以得到其中公共子串:b c b a 和 b d a b。
總感覺,上面這個過程說的不是很清楚,但是不知道怎麼才能更加清楚的表述??糾結啊。
四、**實現
//**實現比較簡單,有可能不符合規矩,如有哪位前輩看到後,可以指出,我會虛心學習。
1 #include
2 #include <
string
>
3 using namespace std;
4 int main(
int argc, char *
*argv)5 }
;13
14 int i = 0;
15 int j = 0;
16 17
for(i = 1; i <
= x_len; i++)
18 25
else
26 32
else
33 36
}37
38 }
39 }
41 for(i = 0 ; i <= x_len; i++)
42
47 cout << endl;
48 }
49 for(i = x_len, j = y_len; i >= 1 && j >= 1;)
50
57 else
58
64 else
65
68 }
69 }
70 cout << endl;
71 return 0;
72 }
執行結果如下所示。
圖2 執行效果
最後輸出為a b c b,則最大子串為b c b a。
其實,應該將結果儲存起來,然後,正序列印呢。
最長公共子串行(LCS)問題
問題描述 見演算法導論p208 p209 前提概念 給定乙個序列x x1,x2,xm 對i 0,1,m,記x的第i個字首為xi x1,x2,xi 故xm x,而x0是個空序列 乙個給定序列的子串行就是該序列去掉0個或多個元素 不一定連續 如bcdb是abcbdab的乙個子串行 基於以上定義,最長公共...
最長公共子串行問題LCS
乙個給定序列的子串行是指在原序列順序不變的基礎上刪去若干元素後得到的序列。給定兩個序列x和y,當乙個序列z既是x的子串行又是y的子串行時,稱z序列為x和y 的公共子串行。例如,x a,b,c,b,d,a,b y b,d,c,a,b,a 則序列 b,c,a 是x和y的乙個公共子串行,但不是x和y的最長...
最長公共子串行 LCS 問題
前言 學習過的知識,只要不經常使用就會忘記,所以在此寫部落格,記錄下來,方便自己,也可能有利於他人。最長公共子串行 lcs 問題。1.什麼是最長公共子串行?最長公共子串行,英文縮寫為lcs longest common subsequence 其定義是,乙個序列 s 如果分別是兩個或多個已知序列的子...