最長公共子串(the longest common substring)
lcs問題就是求兩個字串最長公共子串的問題。解法就是用乙個矩陣來記錄兩個字串中所有位置的兩個字元之間的匹配情況,若是匹配則為1,否則為0。然後求出對角線最長的1的序列,其對應的位置就是最長匹配子串的位置。
def find_lcsubstr(s1, s2):
m=[[0 for i in range(len(s2)+1)] for j in range(len(s1)+1)] #生成0矩陣,為方便後續計算,比字串長度多了一列
mmax=0 #最長匹配的長度
p=0 #最長匹配對應在s1中的最後一位
for i in range(lewww.cppcns.comn(s1)):
for j in range(len(s2)):
if s1[i]==s2[j]:
m[i+1][j+1]=m[i][j]+1
if m[i+1][j+1]>mmax:
mmax=m[i+1][j+1]
p=i+1
return s1[p-mmax:p],mmax #返回最長子串及其長度
print find_lcswww.cppcns.comubstr('abcdfg','abdfg')
執行得到輸出:('dfg',3)
最長公共子串行 (the longest common subsequence)
子串要求字元必須是連續的,但是子串行就不是這樣。最長公共子串行是乙個十分實用的問題,它可以描述兩段文字之間的「相似度」,即它們的雷同程度,從而能夠用來辨別抄襲。對一段文字進行修改之後,計算改動前後文字的最長公共子串行,將除此子串行外的部分提取出來,這種方法判斷修改的部分,往往十分準確。
解法就是用動態回歸的思想,乙個矩陣記錄兩個字串中匹配情況,若是匹配則為左上方的值加1,否則為左方和上方的最大值。乙個矩陣記錄轉移方向,然後根據轉移方向,回溯找到最長子序列。
import numpy
def find_lcseque(s1, s2):
# 生成字串長度加1的0矩陣,m用來儲存對應位置匹配的結果
m = [ [ 0 for x in range(len(s2)+1) ] for y in rnjiydkbange(len(s1)+1) ]
# d用來記錄轉移方向
d = [ [ none for x in range(len(s2)+1) ] for y in range(len(s1)+1) ]
for p1 in range(len(s1)):
for p2 in range(len(s2)):
if s1[p1] == s2[p2]: #字元匹配成功,則該位置的值為左上方的值加1
m[p1+1][p2+1] = m[p1][p2]+1
d[p1+1][p2+1] = 'ok'
elif m[p1+1][p2] > m[p1][p2+1]: #左值大於上值,則該位置的值為左值,並標記回溯時的方向
m[p1+1][p2+1] = m[p1+1][p2]
d[p1+1][p2+1] = 'left'
else: #上值大於左值,則該位置的值為程式設計客棧上值,並標記方向up
m[p1+1][p2+1] = m[p1][p2+1]
d[p1+1][p2+1] = 'up'
(p1, p2) = (len(s1), len(s2))
print numpy.array(d)
s =
while m[p1][p2]: #不為none時
c = d[p1][p2]
if c == 'ok': #匹配成功,插入該字元,並向左上角找下乙個
s.append(s1[p1-1])
p1-=1
p2-=1
if c =='left': #根據標記,向左找下乙個
p2 -= 1
if c == 'up': #根據標記,向上找下乙個
p1 -= 1
s.reverse()
return ''.join(s)
print find_lcseque('abdfg','abcdfg')
得到輸出結果:
本文標題: 詳解python最長公共子串和最長公共子串行的實現
本文位址: /jiaoben/python/232243.html
最長公共子串和最長公共子串行
二者含義沒搞清楚,雅虎的筆試就這樣的寫錯了。求最長公共字串的題目寫成了最長公共子串行。子串要求字元必須是連續的,但是子串行就不是這樣了。悲催了。子串行跟子串的求法類似,都是使用動態規劃的思想,s1每次增加乙個字元,看與s2當前位置的字元是不是相同,如果相同做相應的處理,如果不同,做另外的處理。子串行...
最長公共子串行和最長公共子串
問題定義 最長公共子串行,序列的意思是順序對就可以,並不需要是連續的。例如 abcde oalblcldle其中abcde就是這兩個字串的最長公共子串行。容易知道乙個長度為n的字串的子串行有2 n 個,假設兩個字串的長度都為n,直接去求解兩個字串的最長公共子串行需要用這2 n 個序列串去匹配另外乙個...
最長公共子串行 最長公共子串
1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...