最長公共子串行(LCS)

2021-07-04 11:15:29 字數 1748 閱讀 6555

子問題的遞迴結構

由最長公共子串行問題的最優子結構性質可知,要找出

xm=和

yn=的最長公共子串行,可按如下方式遞迴的進行:

·當xm = yn時,找出xm-1和yn-1的最長公共子串行,然後在其尾部加上xm或yn,即可得到x和y的乙個最長公共子串行; ·

當xm≠yn時,必須解兩個子問題,即找出xm-1和y的乙個最長公共子串行及x和yn-1的乙個最長公共子串行。這兩個公共子串行中較長者即為x和y的乙個最長公共子串行。

由此遞迴結構容易看到最長公共子串行問題具有子問題重疊性質。例如,在計算x和y的最長公共子串行時,可能要計算出x和yn-1以及xm-1和y的最長公共子串行。而這兩個子問題都包含乙個公共子問題,即計算xm-1和yn-1的最長公共子串行。

與矩陣乘積最優計算次序問題類似,我們來建立子問題的最優值的遞迴關係。用c[i,j]記錄序列xi和yj的最長公共子串行的長度,其中xi=,yj=。當i = 0或j = 0時,空序列是xi和yj的最長公共子串行,故c[i,j] = 0。其他情況下,可得遞迴關係如下所示:

由演算法lcs_length計算得到的陣列b 可用於快速構造序列x=和y=的最長公共子串行。首先從b[m,n]開始,沿著其中的箭頭所指的方向在陣列b中搜尋。

·當 b[i,j]中遇到"↖"時(意味著 xi=yi是lcs的乙個元素 ),表示 xi與 yj的最長公共子串行是由 子串行xi-1與 yj-1的最長公共子串行在尾部加上xi得到的子串行;

·當 b[i,j]中遇到"↑" 時,表示 xi與 yj的最長公共的最長公共子串行和xi-1與 yj的最長公共子串行 相同;

·當b[i,j]中遇到"←" 時,表示xi與yj的最長公共子串行和xi與yj-1的最長公共子串行相同;

我來說明下此圖(參考演算法導論)。在序列x=和 y=上,由lcs_length計算出的表c和b。第i行和第j列中的方塊包含了c[i,j]的值以及指向b[i,j]的箭頭。在c[7,6]的項4,表的右下角為x和y的乙個lcs的長度。對於i,j>0,項c[i,j]僅依賴於是否有xi=yi,及項c[i-1,j]和c[i,j-1]的值,這幾個項都在c[i,j]之前計算。為了重構乙個lcs的元素,從右下角開始跟蹤b[i,j]的箭頭即可,這條路徑標示為陰影,這條路徑上的每乙個「↖」對應於乙個使xi=yi為乙個lcs的成員的項(高亮標

兩重迴圈方法

使用兩重迴圈進行字串的對齊匹配過程如下圖所示:

第一重迴圈確定第乙個字串的對齊位置,第二重迴圈確定第二個字串的對齊位置,每次迴圈確定一組兩個字串的對齊位置,並從此對齊位置開始匹配兩個字串的最長子串,如果匹配到的最長子串比已知的(由前面的匹配過程找到的)最長子串長,則更新已知最長子串的內容。兩重迴圈的實現演算法如下:

圖(1)兩重迴圈字串對齊匹配示意圖

#include#include#define max(a,b) (a>b?a:b)

char s1[1010],s2[1010];

int dp[1010][1010];

int main()

else

dp[i][j]=max(dp[i-1][j],dp[i][j-1]);}}

printf("%d\n",dp[len1][len2]);

}}

LCS 最長公共子串行

問題描述 我們稱序列z z1,z2,zk 是序列x x1,x2,xm 的子串行當且僅當存在嚴格上 公升的序列 i1,i2,ik 使得對 j 1,2,k,有 xij zj。比如z a,b,f,c 是 x a,b,c,f,b,c 的子串行。現在給出兩個序列 x和 y,你的任務是找到 x和 y的最大公共子...

LCS最長公共子串行

求兩個字串的最大公共子串行問題 子串行的定義 若給定序列x 則另一串行z 是x的子串行是指存在乙個嚴格遞增下標序列使得對於所有j 1,2,k有 zj xij。例如,序列z 是序列x 的子序列,相應的遞增下標序列為。分析 用動態規劃做 1.最長公共子串行的結構 事實上,最長公共子串行問題具有最優子結構...

LCS最長公共子串行

lcs是longest common subsequence的縮寫,即最長公共子串行。乙個序列,如果是兩個或多個已知序列的子串行,且是所有子串行中最長的,則為最長公共子串行。複雜度對於一般的lcs問題,都屬於np問題。當數列的量為一定的時,都可以採用動態規劃去解決。解法動態規劃的乙個計算最長公共子串...