詳解Python最長公共子串和最長公共子序列的實現(xiàn)
最長公共子串(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矩陣,為方便后續(xù)計算,比字符串長度多了一列
mmax=0 #最長匹配的長度
p=0 #最長匹配對應在s1中的最后一位
for i in range(len(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_lcsubstr('abcdfg','abdfg')
運行得到輸出:('dfg',3)
最長公共子序列 (The Longest Common Subsequence)
子串要求字符必須是連續(xù)的,但是子序列就不是這樣。最長公共子序列是一個十分實用的問題,它可以描述兩段文字之間的“相似度”,即它們的雷同程度,從而能夠用來辨別抄襲。對一段文字進行修改之后,計算改動前后文字的最長公共子序列,將除此子序列外的部分提取出來,這種方法判斷修改的部分,往往十分準確。
解法就是用動態(tài)回歸的思想,一個矩陣記錄兩個字符串中匹配情況,若是匹配則為左上方的值加1,否則為左方和上方的最大值。一個矩陣記錄轉移方向,然后根據(jù)轉移方向,回溯找到最長子序列。
import numpy
def find_lcseque(s1, s2):
# 生成字符串長度加1的0矩陣,m用來保存對應位置匹配的結果
m = [ [ 0 for x in range(len(s2)+1) ] for y in range(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': #根據(jù)標記,向左找下一個
p2 -= 1
if c == 'up': #根據(jù)標記,向上找下一個
p1 -= 1
s.reverse()
return ''.join(s)
print find_lcseque('abdfg','abcdfg')
得到輸出結果:

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
使用spyder3調試python程序的實現(xiàn)步驟
本文主要介紹了使用spyder3調試python程序的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12
Centos Python2 升級到Python3的簡單實現(xiàn)
下面小編就為大家?guī)硪黄狢entos Python2 升級到Python3的簡單實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-06-06
python結合多線程爬取英雄聯(lián)盟皮膚(原理分析)
多線程是為了同步完成多項任務,不是為了提高運行效率,而是為了提高資源使用效率來提高系統(tǒng)的效率。這篇文章主要介紹了python爬取英雄聯(lián)盟皮膚結合多線程的方法,需要的朋友可以參考下2021-05-05
Python中urllib+urllib2+cookielib模塊編寫爬蟲實戰(zhàn)
這篇文章主要介紹了Python的urllib+urllib2+cookielib模塊編寫爬蟲實戰(zhàn),文中給出了抓取豆瓣同城和登陸圖書館查詢圖書歸還的爬取例子,需要的朋友可以參考下2016-01-01

