<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    走在架構師的大道上 Jack.Wang's home

    Java, C++, linux c, C#.net 技術,軟件架構,領域建模,IT 項目管理 Dict.CN 在線詞典, 英語學習, 在線翻譯

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      195 Posts :: 3 Stories :: 728 Comments :: 0 Trackbacks
     

    計算字符串相似度的簡易算法

    算法設計背景:

    最近設計知識管理系統的資源導入功能,為了盡量的做到組件化,方便擴展,方便其他模塊使用。簡化組件提供的和需要的接口,設計并實現了基于 Mapping 機制的導入框架。其中有一功能用到了計算兩個字符串相似度的算法,簡單設計如下以便參考:

    設計思想:

       把兩個字符串變成相同的基本操作定義如下:

    1.     修改一個字符(如把 a 變成 b

    2.     增加一個字符 ( abed 變成 abedd)

    3.     刪除一個字符(如 jackbllog 變成 jackblog

    針對于 jackbllogjackblog 只需要刪除一個或增加一個 l 就可以把兩個字符串變為相同。把這種操作需要的次數定義為兩個字符串的距離 L, 則相似度定義為 1/(L+1) 即距離加一的倒數。那么jackbllogjackblog的相似度為 1/1+1=1/2=0.5 也就是所兩個字符串的相似度是 0.5,說明兩個字符串已經很接近啦。

    任意兩個字符串的距離都是有限的,都不會超過他們的長度之和,算法設計中我們并不在乎通過一系列的修改后,得到的兩個相同字符串是什么樣子。所以每次只需一步操作,并遞歸的進行下一計算。JAVA 的實現如下:

     1/**
     2 * 
     3 */

     4package org.blogjava.arithmetic;
     5
     6import java.util.HashMap;
     7import java.util.Map;
     8
     9/**
    10 * @author jack.wang
    11 * 
    12 */

    13public class StringDistance {
    14
    15    public static final Map<String, String> DISTANCE_CACHE = new HashMap<String, String>();
    16
    17    private static int caculateStringDistance(byte[] firstStr, int firstBegin,
    18            int firstEnd, byte[] secondStr, int secondBegin, int secondEnd) {
    19        String key = makeKey(firstStr, firstBegin, secondStr, secondBegin);
    20        if (DISTANCE_CACHE.get(key) != null{
    21            return Integer.parseInt(DISTANCE_CACHE.get(key));
    22        }
     else {
    23            if (firstBegin >= firstEnd) {
    24                if (secondBegin >= secondEnd) {
    25                    return 0;
    26                }
     else {
    27                    return secondEnd - secondBegin + 1;
    28                }

    29            }

    30            if (secondBegin >= secondEnd) {
    31                if (firstBegin >= firstEnd) {
    32                    return 0;
    33                }
     else {
    34                    return firstEnd - firstBegin + 1;
    35                }

    36            }

    37            if (firstStr[firstBegin] == secondStr[secondBegin]) {
    38                return caculateStringDistance(firstStr, firstBegin + 1,
    39                        firstEnd, secondStr, secondBegin + 1, secondEnd);
    40            }
     else {
    41                int oneValue = caculateStringDistance(firstStr, firstBegin + 1,
    42                        firstEnd, secondStr, secondBegin + 2, secondEnd);
    43                int twoValue = caculateStringDistance(firstStr, firstBegin + 2,
    44                        firstEnd, secondStr, secondBegin + 1, secondEnd);
    45                int threeValue = caculateStringDistance(firstStr,
    46                        firstBegin + 2, firstEnd, secondStr, secondBegin + 2,
    47                        secondEnd);
    48                DISTANCE_CACHE.put(key, String.valueOf(min(oneValue, twoValue,
    49                        threeValue) + 1));
    50                return min(oneValue, twoValue, threeValue) + 1;
    51            }

    52        }

    53    }

    54
    55    public static float similarity(String stringOne, String stringTwo) {
    56        return 1f / (caculateStringDistance(stringOne.getBytes(), 0, stringOne
    57                .getBytes().length - 1, stringTwo.getBytes(), 0, stringOne
    58                .getBytes().length - 1+ 1);
    59    }

    60
    61    private static int min(int oneValue, int twoValue, int threeValue) {
    62        return oneValue > twoValue ? twoValue
    63                : oneValue > threeValue ? threeValue : oneValue;
    64    }

    65
    66    private static String makeKey(byte[] firstStr, int firstBegin,
    67            byte[] secondStr, int secondBegin) {
    68        StringBuffer sb = new StringBuffer();
    69        return sb.append(firstStr).append(firstBegin).append(secondStr).append(
    70                secondBegin).toString();
    71    }

    72
    73    /**
    74     * @param args
    75     */

    76    public static void main(String[] args) {
    77        float i = StringDistance.similarity("jacklovvedyou""jacklodveyou");
    78        System.out.println(i);
    79    }

    80}

    81




    本博客為學習交流用,凡未注明引用的均為本人作品,轉載請注明出處,如有版權問題請及時通知。由于博客時間倉促,錯誤之處敬請諒解,有任何意見可給我留言,愿共同學習進步。
    posted on 2009-01-19 23:53 Jack.Wang 閱讀(11007) 評論(9)  編輯  收藏 所屬分類: 開發技術數學&算法

    Feedback

    # re: 計算字符串相似度的簡易算法 2009-01-20 09:37 Anonymous
    看看算法書再來吧  回復  更多評論
      

    # re: 計算字符串相似度的簡易算法[未登錄] 2009-01-20 10:44 IceRao
    使用向量吧。  回復  更多評論
      

    # re: 計算字符串相似度的簡易算法 2009-01-20 10:59 夜弓
    字符串不是字節流
    相似度是不好這樣簡單算的
    比如
    helloworld
    hollywood
    9個字母里面就有6個相同
    顯然不是那么簡單回事  回復  更多評論
      

    # re: 計算字符串相似度的簡易算法 2009-01-20 16:29 Anonymous
    計算編輯距離是個好想法,但還是有局限性的

    另外你的相似度計算公式從分布上并不很natural,比如兩個長度在30的單詞,如果編輯距離為1,他們的相似度會比兩個長度在5編輯距離為1的單詞要更加高一些(我覺得這樣的想法會更natural一點)。

    從編輯距離本身的定義角度,我覺得還是不適合作為字符串相似的量度的,但可以作為輔助手段來對可能的錯誤輸入產生提示。  回復  更多評論
      

    # re: 計算字符串相似度的簡易算法 2009-01-20 20:21 Jack.Wang
    這么多人回復啊!
    @Anonymous
    恩,說的很好,謝謝啦!之前沒看相關的算法書,只是有這個想法!順便寫了寫!應該有更好的量度來計算兩個字符串的相似度!等看看算法書或者有 blog 友貼貼!  回復  更多評論
      

    # re: 計算字符串相似度的簡易算法 2009-08-29 23:41 cricket
    遞歸算法的復雜度非常高,動態規劃算法能把復雜度降到O(M*N),改進后能到O(N+K^2),自動機和bit-parallelism算法甚至能到O(N)  回復  更多評論
      

    # re: 計算字符串相似度的簡易算法 2009-10-14 14:54 yeluolei
    有那么簡單么……  回復  更多評論
      

    # re: 計算字符串相似度的簡易算法 2009-12-17 14:02 黃凱
    是的,使用編輯距離(尤其是改良后的Levenshtein算法)其算法復雜度可以縮短至O(2k+1)。不過lz的思想和Levenshtein算法的初衷本質上是一致的,還是值得贊賞的,可惜人家比你早很多年提出來~  回復  更多評論
      

    # re: 計算字符串相似度的簡易算法 2010-03-25 09:18 szx
    老大,這是《編程之美》上的原題源代碼  回復  更多評論
      

    主站蜘蛛池模板: 亚洲精品在线免费观看视频| 国产在线精品一区免费香蕉| 亚洲人成在线播放网站岛国| 国产高清免费观看| **毛片免费观看久久精品| 久久久久久av无码免费看大片| 亚洲精品av无码喷奶水糖心| 亚洲成av人片不卡无码| 亚洲av无码精品网站| 国产亚洲AV手机在线观看| 日韩免费无码一区二区视频| 2021久久精品免费观看| 一级毛片**不卡免费播| 两个人看的www高清免费视频| 免费看黄网站在线看| 亚洲国产精品网站在线播放| 国产成人精品亚洲2020| 亚洲成人高清在线观看| 精品无码一区二区三区亚洲桃色| 久久精品国产亚洲综合色| 黑人大战亚洲人精品一区| 久久精品亚洲福利| 久久亚洲精品无码观看不卡| 亚洲国产天堂久久综合| 亚洲AⅤ优女AV综合久久久| 日韩黄色免费观看| 在线观看91精品国产不卡免费| 在线观看免费宅男视频| 免费精品人在线二线三线区别 | xvideos亚洲永久网址| 国产在线98福利播放视频免费| 四虎影视大全免费入口| 成人午夜视频免费| 午夜高清免费在线观看| 日韩视频在线免费观看| 四虎影视在线永久免费观看| 亚洲国产天堂久久久久久| 中国亚洲女人69内射少妇| 国产成人亚洲综合无码精品| 亚洲国产一区在线| 亚洲午夜一区二区电影院|