計算字串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...