演算法導論程式38 最長公共子串行(Python)

2021-08-01 20:35:49 字數 2753 閱讀 8874

最長公共子串行問題:

s1=accggtcgagtgcgcggaagccggccgaa

s2=gtcgttcggaatgccgttgctctgtaaa

相似度的衡量:

尋找第三個串s3,它的所有鹼基也都出現在s1和s2中,且在三個串中出現的順序都相同,但在s1和s2中不要求連續出現。可以找到的s3越長,就可以認為s1和s2的相似度越高。

s3=gtcgtcggaagccggccgaa

乙個給定序列的子串行,就是將給定的序列中零個或多個元素去掉之後得到的結果。

其形式化定義如下:給定乙個序列x=,另乙個序列z=滿足如下條件時稱為x的子串行。即存在嚴格遞增的x的下標序列

給定兩個序列x和y,如果z既是x的子串行,也是y的子串行,我們稱它是x和y的公共子串行。

最長公共子串行問題(longest-common-subsequence problem):

給定兩個序列x=和y=,求x和y長度最長的公共子串行。本節將展示如何用動態規劃方法高效地求解lcs問題。

與矩陣鏈乘法問題相似:設計lcs問題的遞迴演算法首先要建立最優解的遞迴式。

我們定義c[i, j]表示xi和yj的lcs的長度。

計算lcs的長度:

過程lcs-length接受兩個序列x=和y=為輸入,它將c[i, j]的值儲存在表c[0..m 0..n]中,並按行主次序計算表項。過程還維護乙個表b[1..m 1..n]幫助構造最優解。b[i, j]指向的表項對應計算c[i, j]時所選擇的子問題最優解。過程返回表b和表c,c[m , n]儲存了x和y的lcs的長度。

def lcs_length(x,y):

m=len(x)

n=len(y)

c=[[0 for j in range(n+1)]for i in range(m+1)]

b=[[" " for j in range(n+1)]for i in range(m+1)]

for i in range(1,m+1):

for j in range(1,n+1):

if x[i-1]==y[j-1]:

c[i][j]=c[i-1][j-1]+1

b[i][j]="left up"

elif c[i-1][j]>=c[i][j-1]:

c[i][j]=c[i-1][j]

b[i][j]="up"

else:

c[i][j]=c[i][j-1]

b[i][j]="left"

return c,b

def print_lcs(b,x,i,j):

if i==0 or j==0:

return

if b[i][j]=="left up":

print_lcs(b,x,i-1,j-1)

print(x[i-1],end='')

elif b[i][j]=="up":

print_lcs(b,x,i-1,j)

else:

print_lcs(b,x,i,j-1)

if __name__=="__main__":

x=["a","b","c","b","d","a","b"]

y=["b","d","c","a","b","a"]

c,b=lcs_length(x,y)

for i in range(len(x)+1):

for j in range(len(y)+1):

print(c[i][j],' ',end='')

print()

for i in range(len(x)+1):

for j in range(len(y)+1):

print(b[i][j],' ',end='')

print()

print_lcs(b,x,len(x),len(y))

執行:

0  0  0  0  0  0  0  

0 0 0 0 1 1 1

0 1 1 1 1 2 2

0 1 1 2 2 2 2

0 1 1 2 2 3 3

0 1 2 2 2 3 3

0 1 2 2 3 3 4

0 1 2 2 3 4 4

up up up left up left left up

left up left left up left up left

up up left up left up up

left up up up up left up left

up left up up up up up

up up up left up up left up

left up up up up left up up

bcba

過程的執行時間為o(m+n),因為每次遞迴呼叫i和j至少有乙個會減少1。

演算法導論 最長公共子串行

華電北風吹 日期 2016 2 24 問題描述 給定兩個序列x x1,x2,x m 和y y1,y 2,yn 求 x 和 y的長度最長的公共子串行。子串行 給定乙個序列x x1,x2,x m 若另乙個序列z z1,z2,z k 滿足存在乙個嚴格遞增的下標序列i1 i2,ik使得對所有的j 1,2,k...

演算法導論 最長公共子串行

一 演算法設計與分析 設計lcs length演算法,概算福接受兩個序列x 1.m y 1.n 為輸入。它將c i,j 的值儲存在表c 0 m,0 n 並按照行主序計算表項。過程維護乙個表b 1 m,1 n 幫助構造最優解。b i,j 指向的表項對應計算c i,j 時所選擇的子問題最優解。偽 如下 ...

演算法 最長公共子串行

好久沒做演算法題了,現在發現自己的演算法能力非常薄弱,所以特意練練,順便做個筆記方便以後檢視。今天整理一下最長公共子串行,最長公共子串行的問題常用於解決字串的相似度,是乙個非常實用的演算法,作為碼農,此演算法是我們的必備基本功。最長公共子串行,是指兩個字串可具有的長度最大的公共的子串行。聽著好像有點...