todayx.org
          todayx.org
          posts - 39,comments - 60,trackbacks - 0

          0.這個算法實現(xiàn)起來很簡單

          1.百度百科介紹:

          Levenshtein 距離,又稱編輯距離,指的是兩個字符串之間,由一個轉(zhuǎn)換成另一個所需的最少編輯操作次數(shù)。

          許可的編輯操作包括將一個字符替換成另一個字符,插入一個字符,刪除一個字符。

          編輯距離的算法是首先由俄國科學(xué)家Levenshtein提出的,故又叫Levenshtein Distance。

          2.用途

          模糊查詢

          3.實現(xiàn)過程

          a.首先是有兩個字符串,這里寫一個簡單的 abc和abe

          b.將字符串想象成下面的結(jié)構(gòu)。

          A處 是一個標記,為了方便講解,不是這個表的內(nèi)容。

           


          abc a b c
          abe 0 1 2 3
          a 1 A處

          b 2


          e 3


          c.來計算A處 出得值

          它的值取決于:左邊的1、上邊的1、左上角的0.

          按照Levenshtein distance的意思:

          上面的值和左面的值都要求加1,這樣得到1+1=2。

          A處 由于是兩個a相同,左上角的值加0.這樣得到0+0=0。

          這是后有三個值,左邊的計算后為2,上邊的計算后為2,左上角的計算為0,所以A處 取他們里面最小的0.

          d.于是表成為下面的樣子


          abc a b c
          abe 0 1 2 3
          a 1 0

          b 2 B處

          e 3


          B處 會同樣得到三個值,左邊計算后為3,上邊計算后為1,在B處 由于對應(yīng)的字符為a、b,不相等,所以左上角應(yīng)該在當前值的基礎(chǔ)上加1,這樣得到1+1=2,在(3,1,2)中選出最小的為B處的值。

          e.于是表就更新了

           


          abc a b c
          abe 0 1 2 3
          a 1 0

          b 2 1

          e 3 C處

          C處 計算后:上面的值為2,左邊的值為4,左上角的:a和e不相同,所以加1,即2+1,左上角的為3。

          在(2,4,3)中取最小的為C處 的值。

          f.于是依次推得到



          a b c

          0 1 2 3
          a 1 A處 0 D處 1 G處 2
          b 2 B處 1 E處 0 H處 1
          e 3 C處 2 F處 1 I處 1

           

          I處: 表示abc 和abe 有1個需要編輯的操作。這個是需要計算出來的。

          同時,也獲得一些額外的信息。

          A處: 表示a      和a      需要有0個操作。字符串一樣

          B處: 表示ab    和a      需要有1個操作。

          C處: 表示abe  和a      需要有2個操作。

          D處: 表示a      和ab    需要有1個操作。

          E處: 表示ab    和ab    需要有0個操作。字符串一樣

          F處: 表示abe  和ab    需要有1個操作。

          G處: 表示a      和abc   需要有2個操作。

          H處: 表示ab    和abc    需要有1個操作。

          I處: 表示abe   和abc    需要有1個操作。

          g.計算相似度

          先取兩個字符串長度的最大值maxLen,用1-(需要操作數(shù)除maxLen),得到相似度。

          例如abc 和abe 一個操作,長度為3,所以相似度為1-1/3=0.666。

          4.代碼實現(xiàn)

          直接能運行, 復(fù)制過去就行。

          Java代碼  收藏代碼
          1. package code;  
          2.   
          3. /** 
          4.  * @className:MyLevenshtein.java 
          5.  * @classDescription:Levenshtein Distance 算法實現(xiàn) 
          6.  * 可以使用的地方:DNA分析   拼字檢查   語音辨識   抄襲偵測 
          7.  * @author:donghai.wan 
          8.  * @createTime:2012-1-12 
          9.  */  
          10. public class MyLevenshtein {  
          11.   
          12.     public static void main(String[] args) {  
          13.         //要比較的兩個字符串  
          14.         String str1 = "今天星期四";  
          15.         String str2 = "今天是星期五";  
          16.         levenshtein(str1,str2);  
          17.     }  
          18.   
          19.     /** 
          20.      *   DNA分析   拼字檢查   語音辨識   抄襲偵測 
          21.      *  
          22.      * @createTime 2012-1-12 
          23.      */  
          24.     public static void levenshtein(String str1,String str2) {  
          25.         //計算兩個字符串的長度。  
          26.         int len1 = str1.length();  
          27.         int len2 = str2.length();  
          28.         //建立上面說的數(shù)組,比字符長度大一個空間  
          29.         int[][] dif = new int[len1 + 1][len2 + 1];  
          30.         //賦初值,步驟B。  
          31.         for (int a = 0; a <= len1; a++) {  
          32.             dif[a][0] = a;  
          33.         }  
          34.         for (int a = 0; a <= len2; a++) {  
          35.             dif[0][a] = a;  
          36.         }  
          37.         //計算兩個字符是否一樣,計算左上的值  
          38.         int temp;  
          39.         for (int i = 1; i <= len1; i++) {  
          40.             for (int j = 1; j <= len2; j++) {  
          41.                 if (str1.charAt(i - 1) == str2.charAt(j - 1)) {  
          42.                     temp = 0;  
          43.                 } else {  
          44.                     temp = 1;  
          45.                 }  
          46.                 //取三個值中最小的  
          47.                 dif[i][j] = min(dif[i - 1][j - 1] + temp, dif[i][j - 1] + 1,  
          48.                         dif[i - 1][j] + 1);  
          49.             }  
          50.         }  
          51.         System.out.println("字符串\""+str1+"\"與\""+str2+"\"的比較");  
          52.         //取數(shù)組右下角的值,同樣不同位置代表不同字符串的比較  
          53.         System.out.println("差異步驟:"+dif[len1][len2]);  
          54.         //計算相似度  
          55.         float similarity =1 - (float) dif[len1][len2] / Math.max(str1.length(), str2.length());  
          56.         System.out.println("相似度:"+similarity);  
          57.     }  
          58.   
          59.     //得到最小值  
          60.     private static int min(int... is) {  
          61.         int min = Integer.MAX_VALUE;  
          62.         for (int i : is) {  
          63.             if (min > i) {  
          64.                 min = i;  
          65.             }  
          66.         }  
          67.         return min;  
          68.     }  
          69.   
          70. }  

          5.猜測原理

          為什么這樣就能算出相似度了?

          首先在連續(xù)相等的字符就可以考慮到

          紅色是取值的順序。

          1.今天周一    天周一

           




          0 1 2 3
          1 1 2 3
          2 1 2 3
          3 2 1 3
          4 3 3 1

          實現(xiàn)是去掉“今”,一步完成。

          2.聽說馬上就要放假了 你聽說要放假了

           




          0 1 2 3 4 5 6 7
          1 1 1 2 3 4 5 6
          2 2 2 1 2 3 4 5
          3 3 3 2 2 3 4 5
          4 4 4 3 3 3 4 5
          5 5 5 4 4 4 4 5
          6 6 6 5 4 5 5 5
          7 7 7 6 5 4 5 6
          8 8 8 7 6 5 4 6
          9 9 9 8 7 6 6 4

          這兩個字符串是:

          去掉“你”,加上“馬上就”,總共四步操作。

          3.還是沒弄懂

          6.結(jié)束

          算法優(yōu)化空間很大。

          最后也沒弄懂為什么這樣算能算出相似度。


          轉(zhuǎn)自iteye

          歷史上的今天
          回顧歷史的今天,歷史就像生活的一面鏡子;可以了解歷史的這一天發(fā)生的事件;借古可以鑒今;歷史是不能忘記的.要記住歷史的每一天
          http://www.todayx.org/
          posted on 2012-01-14 22:08 todayx.org 閱讀(1773) 評論(1)  編輯  收藏

          FeedBack:
          # re: 計算字符串相似度算法 Levenshtein
          2012-02-13 16:05 | Frank Pan
          Fast and Easy Levenshtein distance using a Trie (http://stevehanov.ca/blog/index.php?id=114

          Improving Search with Levenshtein Distance
          http://www.switchplane.com/blog/improving-search-with-levenshtein-distance.php

          文章的 開頭 就告訴你 Levenshtein distance 的用處了.   回復(fù)  更多評論
            

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 綦江县| 古田县| 二手房| 青冈县| 铜川市| 阿拉善左旗| 大余县| 盐亭县| 马边| 手游| 绍兴县| 阜宁县| 锦州市| 如东县| 内丘县| 育儿| 南木林县| 河北省| 万安县| 阿克陶县| 莎车县| 石棉县| 瑞安市| 高雄市| 德阳市| 苏州市| 普定县| 新乐市| 福安市| 大竹县| 长海县| 博罗县| 渭源县| 五大连池市| 班玛县| 澎湖县| 右玉县| 襄垣县| 河西区| 凤山市| 木里|