最長公共子串行(LCS)問題

2021-06-25 15:57:56 字數 1729 閱讀 9208

最長公共子串行(lcs)問題

我們經常遇到:給定兩個序列,求這兩個序列的最長公共子串問題,形式化表示:給定兩個序列x=<>和y=<>,求x和y長度最長的公共子串行,本文將利用動態規劃方法高效地求解lcs(連續和不連續),並分別給出在c編寫的程式。

1、動態規劃法

通過組合子問題的解來求解原問題,通常按照如下的4個步驟來設計乙個動態規劃演算法:

<1>、刻畫乙個最優解的結構特徵。

<2>、遞迴的定義最優解的值。

<3>、計算最優解的值,通常採用自底向上的方法。

<4>、利用計算出的資訊構造乙個最優解。

2、最長公共子串行(不連續)

【lcs的最優子結構】令x=<>和y=<>為兩個序列,為x和y的任意lcs。

<1>、如果,則且是和的乙個lcs。

<2>、如果,則且是和的乙個lcs。

<3>、如果,則且是和的乙個lcs。

可以通過定理方法嚴謹證明!

根據lcs問題的最優子結構的性質,可以得到如下公式:

c程式如下:

int lcs_length(char str1,charstr2)

inti,j;

for(i=0;i<=m;i++)

}for(i=1;i<=m;i++)

}intmax=0;

for(i=1;i<=m;i++)

}free(c);

returnmax;

}

3、最長公共連續子串行(連續)

下面分析一下最長公共連續子串行的求法:因為要求的是公共串必須為連續的,因而在出現的情況時,此時對於就需要從零重新開始。

即對應公式為:

c程式如下:

int strict_lcs_length(charstr1,char str2)

inti,j;

for(i=0;i<=m;i++)

}for(i=1;i<=m;i++)

}intmax=0;

for(i=1;i<=m;i++)

}free(c);

returnmax;

}

上述演算法的時間複雜度為,空間複雜度為,上述演算法還可以進一步改進,我們可以講查詢最大長度和對應字元的工作放在狗仔舉證的過程中完成,這樣可以節省矩陣最大元素查詢的時間。

同樣,對於空間複雜度也可做以改進,將演算法的空間複雜度降為,在上述構造中,當矩陣的第行的值計算完成後,第行的值就沒有作用了,即使最大的長度出現在第行,我們也已經記錄了。故而我們可以用一維向量來處理,向量的當前值對應第i行,向量的下一行對應第i+1行,其中注意記憶體迴圈要從最大值朝最小值變化,否則同一行下表小的更新,會覆蓋掉上一行數值,導致更新錯誤。

其所對應的c程式**為:

#include#include#include#include//計算最長連續公共子串

int lcs_length(char str1,charstr2)

intm=strlen(str1);//計算str1的長度

intn=strlen(str2);//計算str2的長度

int*c=(int*)malloc(sizeof(int)*(n+1));

inti,j;

for(i=0;i0;j--)//注意,必須j從大到小變化,否則還需要使用的舊值被覆蓋

{if(str1[i]==str2[j-1])

{c[j]=c[j-1]+1;

if(max_len

最長公共子串行(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 如果分別是兩個或多個已知序列的子...