一.问题
在计算文本的相似性时,经常会用到编辑距离。编辑距离,又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。通常来说,编辑距离越小,两个文本的相似性越大。这里的编辑操作主要包括三种:
- 插入:将一个字符插入某个字符串;
- 删除:将字符串中的某个字符删除;
- 替换:将字符串中的某个字符替换为另外一个字符。
以上摘自链接[1]
二.解决方式
解决方法有好几种,这里说明动态规划的实现
动态规划的思想是将问题划分为子问题,这个问题的迭代式为:
(1) 当s1[i]=s2[j]时,DP[i][j]=DP[i-1][j-1]
(2) 当s1[i=!=s2[j]时,DP[i][j]=min{DP[i-1][j],DP[i][j-1],DP[i-1][j-1]}+1
DP[i][j]表示s1中以s1[i]结尾的字符串和s2中以s2[j]结尾的子串的编辑距离
关于上面(2)中的子问题的解释:
求以s1[i]和s2[j]结尾的连个子串的编辑距离的问题,可以转换为求解三个子问题:
求解以s1[i-1]和s2[j]结尾的子串的编辑距离;对应的操作是在s1中删除元素s1[i]
求解以s1[i]和s2[j-1]结尾的子串的编辑距离;对应的操作是在s1中元素s1[i]的后面插入一个元素s2[j]
求解以s1[i-1]和s2[j-1]结尾的子串的编辑距离;对应的操作是将元素s1[i]替换为s2[j]
这也是常见的字符串问题的子问题划分思路:比如求两个字符串的最长公共子串、某个字符串的最长回文子串、最长回文子序列
三.python代码实现如下:
def EditDis(s1,s2):
m=len(s1)
n=len(s2)
DP=[[0 for i in range(m)] for j in range(n)]
for i in range(n):
for j in range(m):
if i==0:
DP[i][j]=j
elif j==0:
DP[i][j]=i
else:
if s1[j]==s2[i]:
if i>0 and j>0:
DP[i][j]=DP[i-1][j-1]
else:
DP[i][j]=min(DP[i][j-1],DP[i-1][j],DP[i-1][j-1])+1
return DP[n-1][m-1]
参考链接: