字符串编辑距离(相似度)

编辑距离及编辑距离算法

编辑距离概念描述:

编辑距离,又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

例如将kitten一字转成sitting:

  1. sitten (k→s)
  2. sittin (e→i)
  3. sitting (→g)

俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。

 

问题:找出字符串的编辑距离,即把一个字符串s1最少经过多少步操作变成编程字符串s2,操作有三种,添加一个字符,删除一个字符,修改一个字符


给定一个源串和目标串,能够对源串进行如下操作: 
1.在给定位置上插入一个字符 
2.替换任意字符 
3.删除任意字符 
写一个程序,返回最小操作数,使得对源串进行这些操作后等于目标串,源串和目标串的长度都小于2000。

思路

如果有两个串 A = xabcdae 和 B = xfdfa,它们的第一个字符是相同的,只要计算A[2…7] = abcdae 和 B[2…5] = fdfa的距离就可以了。但是如果两个串的第一个字符不相同,那么可以进行如下的操作(lenA和lenB分别是字符串A和B的长度): 
(1)删除A串的第一个字符,然后计算A[2…lenA]和B[1…lenB]的距离。 
(2)删除B串的第一个字符,然后计算A[1…lenA]和B[2…lenB]的距离。 
(3)修改A串的第一个字符为B串的第一个字符,然后计算A[2…lenA]和B[2…lenB]的距离。 
(4)修改B串的第一个字符为A串的第一个字符,然后计算A[2…lenA]和B[2…lenB]的距离。 
(5)增加B串的第一个字符到A串的第一个字符之前,然后计算A[1…lenA]和B[2…lenB]的距离。 
(6)增加A串的第一个字符到B串的第一个字符之前,然后计算A[2…lenA]和B[1…lenB]的距离。

在这个题目中,我们并不在乎两个字符串变得相等之后的字符串是什么样的。所以,我们可以将上面的6个步骤简化为:

(1)一步操作之后,再将A[2…lenA] 和 B[1…lenB]变成相同的字符串。 
(2)一步操作之后,再将A[1…lenA] 和 B[2…lenB]变成相同的字符串。 
(3)一步操作之后,再将A[2…lenA] 和 B[2…lenB]变成相同的字符串。

这样,很快就可以完成一个递归程序。

在递归的过程中,有些数据被重复计算了。比如,如果我们开始调用StrDistance(A,1,3,B,1,3) 
下图是部分展开的递归调用: 
这里写图片描述
可以看到,圈中的两个子问题被重复计算了。为了避免这种不必要的重复计算,可以把子问题计算后的解储存起来。

思路二

编辑距离是动态规划里面的经典题目。 Edit[i][j]为word1[0..i-1]和word2[0..j-1]的最小编辑数。

状态转移方程: 
这里写图片描述

解析:

首先定义这样一个函数——edit(i, j),它表示第一个字符串的长度为i的子串到第二个字符串的长度为j的子串的编辑距离。

显然可以有如下动态规划公式:

  • if i == 0 且 j == 0,edit(i, j) = 0
  • if i == 0 且 j > 0,edit(i, j) = j
  • if i > 0 且j == 0,edit(i, j) = i
  • if i ≥ 1  且 j ≥ 1 ,edit(i, j) == min{ edit(i-1, j) + 1, edit(i, j-1) + 1, edit(i-1, j-1) + f(i, j) },当第一个字符串的第i个字符不等于第二个字符串的第j个字符时,f(i, j) = 1;否则,f(i, j) = 0。

 

 


0 f a i l i n g
0




  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值