【算法】字符串编辑距离

    字符串的编辑距离即Levenshtein距离,指在两个字符串之间由其中一个字符串通过插入、删除、替换的编辑操作转换为另一个字符串的最小代价,可以当作距离一样来衡量两个字符串之间的相似程度,距离越大则相似程度越低,距离越小则相似程度越高。比如求takers和lakers之间的编辑距离,设插入和删除的代价是1,替换等于删除并插入,故替换的代价是2,takers经过删除t和插入l两步操作可以转换为lakers,那么它们之间的编辑距离就是2。在使用编辑距离时,编辑操作的代价函数可以根据实际情况来进行调整。

    求解编辑距离的过程,我们可以逐个字符考虑,假设现在有两个字符串string1[w1,w2....wn]和string2[c1,c2...cm],w和c分别为string1和string2的字符。

先考虑第一个字符,

    若w1==c1,即两个字符串第一个字符串相等,不需要经过任何编辑操作,编辑距离为0,则我们只需考虑string1[2:n]和string2[2:m]这两个子字符串之间的编辑距离。

    若w1!=c1,则要考虑string1和string2需要什么编辑操作来使得w1=c1:

1.删除string1的第一个字符w1,接着继续计算string1[2:n]和string2[1:m]的编辑距离即可。

2.将string第一个字符替换为c1,两个字符串首字符相等,则继续计算string1[2,n]和string2[2,m]即可。

......

    考虑string1的第i个字符串和string2的第j个字符串时也是用同样的思想,采用动态规划逐步求解最优值。

    下面是编辑距离的计算方法,对于长度为n的string1和长度为m的string2,建立一个(n+2)*(m+2)的表格edit来记录编辑距离。

    edit[i][j]表示string1[0:i]和string2[0:j]的编辑距离,当i=0时,代表string1为空字符串的情况,此时将string1转换为string2就需要将string2的j个字符串插入到string1中,即编辑距离为j,反之当j=0时也是同一种情况。

    当i>0,j>0时,可以考虑通过插入删除和替换哪种操作可以使得string1第i个字符和string第j个字符相等,经过操作之后,当前的编辑距离就是刚刚操作的代价加上子字符串的编辑距离,如此计算,矩阵右下角就是最终两个完整字符串的编辑距离。

表格的填充规则如下:

实例:

计算cafe和coffee的编辑距离:

首先打好表格:

  null c o f f e e
null              
c              
a              
f              
e              

填充第一行第一列

  null c o f f e e
null 0 1 2 3 4 5 6
c 1            
a 2            
f 3            
e 4            

从3,3格开始,开始计算。取以下三个值的最小值:
  • 如果最上方的字符等于最左方的字符,则为左上方的数字。否则为左上方的数字+1。(对于3,3来说为0)
  • 左方数字+1(对于3,3格来说为2)
  • 上方数字+1(对于3,3格来说为2)

  null c o f f e e
null 0 1 2 3 4 5 6
c 1 0          
a 2            
f 3            
e 4            

从3,4(三行四列)格开始,开始计算。取以下三个值的最小值:
  • 如果最上方的字符等于最左方的字符,则为左上方的数字。否则为左上方的数字+1。(对于3,4来说为2)
  • 左方数字+1(对于3,4格来说为1)
  • 上方数字+1(对于3,4格来说为3)

  null c o f f e e
null 0 1 2 3 4 5 6
c 1 0 1        
a 2            
f 3            
e 4            

按此规则递推出整个表:

  null c o f f e e
null 0 1 2 3 4 5 6
c 1 0 1 2 3 4 5
a 2 1 1 2 3 4 5
f 3 2 2 1 2 3 4
e 4 3 3 2 2 2 3
得到右下角编辑距离3。

猜你喜欢

转载自blog.csdn.net/weixin_39837402/article/details/81040203
今日推荐