web-dev-qa-db-ja.com

文字列類似度アルゴリズム?

2つの文字列を比較し、それらの類似度を計算して、最も類似した文字列のリストをフィルタリングする必要があります。

例えば。 「犬」を検索すると戻ります

  1. 犬ぞり
  2. 沼地

例えば。 「クラック」を検索すると戻ります

  1. crack
  2. 賢い
  3. ラック
  4. ジャック
  5. いんちき

私は出会った:

文字列類似度アルゴリズムを知っていますか?

29
Robinicks

何らかのあいまい一致が必要なようです。 Java類似性メトリックのセットの実装 http://www.dcs.shef.ac.uk/~sam/stringmetrics.html 。文字列メトリクスの詳細な説明 http://www.cs.cmu.edu/~wcohen/postscript/ijcai-ws-2003.pdf これは、実装がどれだけファジーでどれくらい速いかによって異なります。

19
Mojo Risin

Levenshtein distanceは、私が推奨するアルゴリズムです。 1つの文字列を別の文字列に変更するために必要な操作の最小数を計算します。変更が少ないということは、文字列がより似ていることを意味します...

26
Peter

これを行うことができます:

Foreachストリング干し草の山行うオフセット := -1; 
 マッチしたキャラクター := 0; 
 Foreachチャー行うオフセット := PositionInString(ストリング、 チャー、 オフセット+1); 
 もしオフセット = -1 それからブレーク; 
 終わり; 
 マッチしたキャラクター := マッチしたキャラクター + 1; 
 終わり; 
 もしマッチしたキャラクター > 0 それから
 //(部分的な)一致が見つかりました
 終わり; 
終わり; 

matchedCharactersを使用すると、一致の「程度」を判断できます。 の長さと等しい場合、のすべての文字は文字列にも含まれます。最初に一致した文字のオフセットも保存する場合、最後に一致した文字のオフセットから最初に一致した文字のオフセットを引くことで、一致した文字の「密度」で結果をソートすることもできますoffset;差が小さいほど、一致の密度が高くなります。

1
Gumbo
class Program { 
    static int ComputeLevenshteinDistance(string source, string target) {
        if ((source == null) || (target == null)) return 0;
        if ((source.Length == 0) || (target.Length == 0)) return 0;
        if (source == target) return source.Length;

        int sourceWordCount = source.Length;
        int targetWordCount = target.Length;

        int[,] distance = new int[sourceWordCount + 1, targetWordCount + 1];

        // Step 2
        for (int i = 0; i <= sourceWordCount; distance[i, 0] = i++);
        for (int j = 0; j <= targetWordCount; distance[0, j] = j++);

        for (int i = 1; i <= sourceWordCount; i++) {
            for (int j = 1; j <= targetWordCount; j++) {
                // Step 3
                int cost = (target[j - 1] == source[i - 1]) ? 0 : 1;

                // Step 4
                distance[i, j] = Math.Min(Math.Min(distance[i - 1, j] + 1, distance[i, j - 1] + 1), distance[i - 1, j - 1] + cost);
            }
        }

        return distance[sourceWordCount, targetWordCount]; 
    }

    static void Main(string[] args){ 
       Console.WriteLine(ComputeLevenshteinDistance ("Stackoverflow","StuckOverflow"));
       Console.ReadKey();
    }
}
0
Indrit Kello