无心间看到了有人问编辑距离算法,当时对这个概念很陌生,也就去学习了下,作下总结,记录下,好记性不如烂笔头。java
编辑距离(Edit Distance):又称Levenshtein距离,是指两个字串之间,由一个转成另外一个所需的最少编辑操做次数。许可的编辑操做包括将一个字符替换成另外一个字符,插入一个字符,删除一个字符,用数据库的说法就是改、增、删;通常来讲就是字符串编辑距离离越小,两个串的类似度越大。python
举个例子:S1=“eeba” S2="abac" 咱们能够按照这样的步骤转变:算法
(1) 将S1中的第一个e变成a;数据库
(2) 删除S1中的第二个e;编程
(3)在S1中最后添加一个c; 那么S1到S2的编辑路径就等于3。编程语言
固然,这种变换并非惟一的,但若是3是全部变换中最小值的话。那么咱们就能够说S1和S2的编辑距离等于3了。函数
据说这个概念是由俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念学习
概念的东西,说多了也只是理论,仍是上代码吧!code
先来份java的吧,这是我工做时用的第一个编程语言:utf-8
publicclassStringSimilar{ //编辑距离求串类似度 publicdoublegetStringSimilar(Strings1,Strings2){ double d[][];//matrix int n;//lengthofs int m;//lengthoft int i;//iteratesthroughs int j;//iteratesthrought char s_i;//ithcharacterofs char t_j;//jthcharacteroft double cost;//cost //第1步 n=s1.length(); m=s2.length(); if(n==0){ return m; } if(m==0){ return n; } d=new double[n+1][m+1]; //第2步 for(i=0;i<=n;i++){ d[i][0]=i; } for(j=0;j<=m;j++){ d[0][j]=j; } //第3步 for(i=1;i<=n;i++){ s_i=s1.charAt(i-1); //第4步 for(j=1;j<=m;j++){ t_j=s2.charAt(j-1); //第5步 if(s_i==t_j){cost=0;}else{cost=1;} //第6步 d[i][j]=Minimum(d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+cost); } } //第7步 return d[n][m]; } //求最小值 privatedoubleMinimum(doublea,doubleb,doublec){ double mi; mi=a; if(b<mi){mi=b;} if(c<mi){mi=c;} return mi;} }
在来一份我最近学习的Python的
#!/user/bin/env python # -*- coding: utf-8 -*- class arithmetic(): def __init__(self): pass def levenshtein(self,first,second): if len(first) > len(second): first,second = second,first if len(first) == 0: return len(second) if len(second) == 0: return len(first) first_length = len(first) + 1 second_length = len(second) + 1 distance_matrix = [range(second_length) for x in range(first_length)] for i in range(1,first_length): for j in range(1,second_length): deletion = distance_matrix[i-1][j] + 1 insertion = distance_matrix[i][j-1] + 1 substitution = distance_matrix[i-1][j-1] if first[i-1] != second[j-1]: substitution += 1 distance_matrix[i][j] = min(insertion,deletion,substitution) print distance_matrix return distance_matrix[first_length-1][second_length-1] if __name__ == "__main__": arith = arithmetic() print arith.levenshtein( 'latino','larou' )
吐槽下:Python语法缩进真是蛋疼,用4个空格缩进来肯定。累的很啊
个人本行iOS的我就不上代码了,代码风格太菜同行到笑话就很差了。能够看出是动态规划解决编辑距离,明白算法原理写出算法函数方法仍是不难的;大概的公式也就是:例S1=“eeba” S2="abac"
若是i=0且j=0 edit(0, 0)=1 若是i=0且j>0 edit(0, j )=edit(0, j-1)+1 若是i>0且j=0 edit( i, 0 )=edit(i-1, 0)+1 若是i>0且j>0 edit(i, j)=min(edit(i-1, j)+1, edit(i,j-1)+1, edit(i-1,j-1)+f(i , j) )
这就是将长字符串间的编辑距离问题一步一步转换成短字符串间的编辑距离问题,直至只有1个字符的串间编辑距离为1