基於編輯距離和最長公共子串計算字串相似度

2022-09-07 15:12:24 字數 2978 閱讀 1566

基於編輯距離和最長公共子串實現的文字相似度計算:

計算公式為

s=lc/(led+lc)

lc為最長公共子串的長度

led為編輯距離

考慮到漢字和字元的不同,增加了str2word()進行字串分詞,實現單字的比較。**寫了一段時間了,有些遺忘。

ld()為編輯距離求解

lcslen()為動態規劃求解最長公共子串問題

lcs()輸出最長公共子串

str2word()進行字串分詞

# -*- coding: utf-8 -*-

from __future__ import division

import re

def ld(firststr,secondstr):

if len(firststr)>len(secondstr):

firststr,secondstr=secondstr,firststr

if len(firststr)==0:

return len(secondstr),0

if len(secondstr)==0:

return len(firststr),0

matrix=[range(len(secondstr)+1) for x in range(len(firststr)+1)]

#print matrix

for i in range(1,len(firststr)+1):

for j in range(1,len(secondstr)+1):

ld1=matrix[i-1][j]+1

ld2=matrix[i][j-1]+1

ld3=matrix[i-1][j-1]

if firststr[i-1]!=secondstr[j-1]:

ld3+=1

matrix[i][j]=min(ld1,ld2,ld3)

#print matrix

ld=matrix[len(firststr)][len(secondstr)]

#print len(secondstr)

return ld

def lcslen(firststr,secondstr):

if len(firststr)>len(secondstr):

firststr,secondstr=secondstr,firststr

if len(firststr)==0:

return len(secondstr),0

if len(secondstr)==0:

return len(firststr),0

matrix=[range(len(secondstr)+1) for x in range(len(firststr)+1)]

#print matrix

for m in range(0,len(firststr)+1):

matrix[m][0]=0

for k in range(1,len(secondstr)+1):

matrix[0][k]=0

for i in range(1,len(firststr)+1):

for j in range(1,len(secondstr)+1):

lcs1=matrix[i-1][j]

lcs2=matrix[i][j-1]

lcs3=matrix[i-1][j-1]

if firststr[i-1]==secondstr[j-1]:

lcs3+=1

matrix[i][j]=max(lcs1,lcs2,lcs3)

#print matrix

lcslen=matrix[len(firststr)][len(secondstr)]

return lcslen

def midlei(i,firststr,secondstr):

strr=''

j=0while ilenmax:

lenmax=len(result)

lenid=i

lc=sen[lenid]

#lcslen=len(lcs)

return lc

def similarity(firststr,secondstr):

s1=str2word(firststr)

s2=str2word(secondstr)

lc=len(lcs(s1,s2))

led=ld(s1,s2)

s=lc/(led+lc)

return s

def preprocess(sen,edcode='utf-8'):

sen=sen.decode(edcode)

sen=re.sub(u"[。,、.,!……!《》<>\"'::?\?、\|「」『』;]","",sen)

#print sen

return sen

def str2word(sen,edcode='utf-8'):

i=0result=

sen=preprocess(sen)

length=len(sen)

while inone:

i+=1

tok=sen[i:i+1]

if i-tempi>0:

#print sen[tempi:i].lower()

#find chinese word

leftword = sen[i:i+1]

if leftword<>" " and ii+=1

return result

if __name__ == '__main__':

first='乙個全球性問題儘管大部分移民並沒有跨出國界 '

second='氣候移民是乙個全球性問題移民並沒有跨出國界但其影響卻是跨國界的'

s=similarity(first,second)

print '相似度為:',s

專題 編輯距離 最長公共子串行 最長公共子陣列

目錄 最長公共子串行 leetcode 1143 最長公共子陣列 leetcode 718 編輯距離1 支援替換 交換 360筆試題 2020.3.24 編輯距離2 支援移動字元到末尾 阿里筆試題 2020.3.27 給定兩個字串text1和text2,返回這兩個字串的最長公共子串行。輸入 text...

最長公共子串和最長公共子串行

二者含義沒搞清楚,雅虎的筆試就這樣的寫錯了。求最長公共字串的題目寫成了最長公共子串行。子串要求字元必須是連續的,但是子串行就不是這樣了。悲催了。子串行跟子串的求法類似,都是使用動態規劃的思想,s1每次增加乙個字元,看與s2當前位置的字元是不是相同,如果相同做相應的處理,如果不同,做另外的處理。子串行...

最長公共子串行和最長公共子串

問題定義 最長公共子串行,序列的意思是順序對就可以,並不需要是連續的。例如 abcde oalblcldle其中abcde就是這兩個字串的最長公共子串行。容易知道乙個長度為n的字串的子串行有2 n 個,假設兩個字串的長度都為n,直接去求解兩個字串的最長公共子串行需要用這2 n 個序列串去匹配另外乙個...