字串相似度演算法(編輯距離演算法 Levenshtein Distance)
在搞驗證碼識別的時候需要比較字元程式碼的相似度用到“編輯距離演算法”,關於原理和C#實現做個記錄。
據百度百科介紹:
編輯距離,又稱Levenshtein距離(也叫做Edit Distance),是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數,如果它們的距離越大,說明它們越是不同。許可的編輯操作包括將一個字元替換成另一個字元,插入一個字元,刪除一個字元。
例如將kitten一字轉成sitting:
sitten (k→s)
sittin (e→i)
sitting (→g)
俄羅斯科學家Vladimir Levenshtein在1965年提出這個概念。因此也叫Levenshtein Distance。
例如
- 如果str1="ivan",str2="ivan",那麼經過計算後等於 0。沒有經過轉換。相似度=1-0/Math.Max(str1.length,str2.length)=1
- 如果str1="ivan1",str2="ivan2",那麼經過計算後等於1。str1的"1"轉換"2",轉換了一個字元,所以距離是1,相似度=1-1/Math.Max(str1.length,str2.length)=0.8
應用 DNA分析
拼字檢查
語音辨識
抄襲偵測
感謝大石頭在評論中給出一個很好的關於此方法應用的連線 補充在此:
小規模的字串近似搜尋,需求類似於搜尋引擎中輸入關鍵字,出現類似的結果列表,文章連線:
演算法過程
- str1或str2的長度為0返回另一個字串的長度。 if(str1.length==0) return str2.length; if(str2.length==0) return str1.length;
- 初始化(n+1)*(m+1)的矩陣d,並讓第一行和列的值從0開始增長。
- 掃描兩字串(n*m級的),如果:str1 == str2[j],用temp記錄它,為0。否則temp記為1。然後在矩陣d[i,j]賦於d[i-1,j]+1 、d[i,j-1]+1、d[i-1,j-1]+temp三者的最小值。
- 掃描完後,返回矩陣的最後一個值d[n][m]即是它們的距離。
計算相似度公式:1-它們的距離/兩個字串長度的最大值。
為了直觀表現,我將兩個字串分別寫到行和列中,實際計算中不需要。我們用字串“ivan1”和“ivan2”舉例來看看矩陣中值的狀況:
1、第一行和第一列的值從0開始增長
i | v | a | n | 1 | ||
0 | 1 | 2 | 3 | 4 | 5 | |
i | 1 | |||||
v | 2 | |||||
a | 3 | |||||
n | 4 | |||||
2 | 5 |
2、i列值的產生 Matrix[i - 1, j] + 1 ; Matrix[i, j - 1] + 1 ; Matrix[i - 1, j - 1] + t
i | v | a | n | 1 | ||
0+t=0 | 1+1=2 | 2 | 3 | 4 | 5 | |
i | 1+1=2 | 取三者最小值=0 | ||||
v | 2 | 依次類推:1 | ||||
a | 3 | 2 | ||||
n | 4 | 3 | ||||
2 | 5 | 4 |
3、V列值的產生
i | v | a | n | 1 | ||
0 | 1 | 2 | ||||
i | 1 | 0 | 1 | |||
v | 2 | 1 | 0 | |||
a | 3 | 2 | 1 | |||
n | 4 | 3 | 2 | |||
2 | 5 | 4 | 3 |
依次類推直到矩陣全部生成
i | v | a | n | 1 | ||
0 | 1 | 2 | 3 | 4 | 5 | |
i | 1 | 0 | 1 | 2 | 3 | 4 |
v | 2 | 1 | 0 | 1 | 2 | 3 |
a | 3 | 2 | 1 | 0 | 1 | 2 |
n | 4 | 3 | 2 | 1 | 0 | 1 |
2 | 5 | 4 | 3 | 2 | 1 | 1 |
最後得到它們的距離=1
相似度:1-1/Math.Max(“ivan1”.length,“ivan2”.length) =0.8
轉載自:http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=981