基礎演算法五 最長公共子串行問題

2021-09-13 12:49:39 字數 1434 閱讀 4145

計算字串a和b之間的最長公共子串行(lcs),同樣是乙個動態規劃問題。我們需要分兩步解決這個問題。首先,我們要找到字串a和b之間的最長公共子串行的長度。然後通過逆序查詢找到最長公共子串行。

我們用table[i][j]表示字串a[1:i],b[1:j]之間的最長公共子串行的長度。很顯然如果a[i]等於b[j],table[i][j]等於table[i-1][j-1]+1。如果a[i]不等於b[j],table[i][j]等於table[i][j-1]和table[i-1][j]中較大的值。於是動態規劃方程可以寫為:

然後我們將思路反過來,根據生成的二維陣列table反向查詢最長公共子串行。整體**如下:

def lcs(a, b):

table = lcs_table(a, b)

lcs = lcs_generate(table, a, len(a), len(b))

return lcs

def lcs_table(a, b):

'''計算最長公共子串行長度

'''table = [[0 for j in range(len(b) + 1)] for i in range(len(a) + 1)]

for i in range(len(a) + 1)[1:]:

for j in range(len(b) + 1)[1:]:

if a[i - 1] == b[j - 1]:

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

else:

table[i][j] = max(table[i - 1][j], table[i][j - 1])

return table

def lcs_generate(table, a, i, j):

'''生成最長公共子串行

'''if table[i][j] == 0:

return ''

if table[i - 1][j] == table[i][j]:

return lcs_generate(table, a, i - 1, j)

elif table[i][j - 1] == table[i][j]:

return lcs_generate(table, a, i, j - 1)

else:

return lcs_generate(table, a, i - 1, j - 1) + a[i - 1]

if __name__ == '__main__':

a = 'abcbdab'

b = 'bdcaba'

print(lcs(a, b))

結果為:

bcba

演算法 最長公共子串行

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

演算法 最長公共子串行

題目 給定兩個字串 text1 和 text2,返回這兩個字串的最長公共子串行的長度。乙個字串的 子串行 是指這樣乙個新的字串 它是由原字串在不改變字元的相對順序的情況下刪除某些字元 也可以不刪除任何字元 後組成的新字串。例如,ace 是 abcde 的子串行,但 aec 不是 abcde 的子串行...

最長公共子串行問題

給定整數a1,a2,an 可能有負值 求連續子串行和的最大值。為方便起見,如果所有整數都為負值,則最大子串行和為0 這是個顯而易見的方法,幾乎每個人在第一眼看到該問題都能夠想出來的方法。就是將所有的子串行找出來,然後求和最大的乙個。如果序列足夠大,該方法的效率可想而知。如下 include incl...