無心間看到了有人問編輯距離算法,當時對這個概念很陌生,也就去學習了下,作下總結,記錄下,好記性不如爛筆頭。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