3

類似の単語に対して類似の数値を生成する何らかの形式のハッシュ アルゴリズムはありますか? 誤検知が多いと思いますが、検索の絞り込みに役立つ可能性があるようです。

編集:Soundexはきちんとしていて便利かもしれませんが、理想的には、次のように動作するものが必要です:abs(f('horse') - f('hoarse')) < abs(f('horse') - f('goat'))

4

4 に答える 4

3

Soundex アルゴリズムは、入力単語の音素に対応するキーの文字列を生成します。http://www.archives.gov/research/census/soundex.html

文字列間の類似性のみを比較したい場合は、Levenstein Distance を試してください。http://en.wikipedia.org/wiki/Levenshtein_distance

于 2011-06-26T13:32:58.433 に答える
1

あなたが話していることはLocality-sensitive Hashingと呼ばれます。さまざまな種類の入力 (画像、音楽、テキスト、空間内の位置など、必要なものは何でも) に適用できます。

残念ながら (検索しても) 文字列用の LSH アルゴリズムの実用的な実装を見つけることができませんでした。

于 2011-07-10T10:31:19.043 に答える
0

いつでもSoundexを試して、ニーズに合っているかどうかを確認できます。

于 2011-06-26T13:36:35.897 に答える
0

ウィキペディアでSoundexアルゴリズムをチェックしてください。言語を指定していませんが、複数の言語での実装例へのリンクがあります。明らかに、これにより、似たような単語と同じ文字列ハッシュが得られ、整数が必要になりますが、Boost.Hashで使用する string->integer ハッシュ メソッドを適用できます。

編集:明確にするために、C++実装の例を次に示します...

#include <boost/foreach.hpp>
#include <boost/functional/hash.hpp>

#include <algorithm>
#include <string>
#include <iostream>

char SoundexChar(char ch)
{
    switch (ch)
    {
        case 'B':
        case 'F':
        case 'P':
        case 'V':
            return '1';
        case 'C':
        case 'G':
        case 'J':
        case 'K':
        case 'Q':
        case 'S':
        case 'X':
        case 'Z':
            return '2';
        case 'D':
        case 'T':
            return '3';
        case 'M':
        case 'N':
            return '5';
        case 'R':
            return '6';
        default:
            return '.';
    }
}

std::size_t SoundexHash(const std::string& word)
{
    std::string soundex;
    soundex.reserve(word.length());

    BOOST_FOREACH(char ch, word)
    {
        if (std::isalpha(ch))
        {
            ch = std::toupper(ch);

            if (soundex.length() == 0)
            {
                soundex.append(1, ch);
            }
            else
            {
                ch = SoundexChar(ch);

                if (soundex.at(soundex.length() - 1) != ch)
                {
                    soundex.append(1, ch);
                }
            }
        }
    }

    soundex.erase(std::remove(soundex.begin(), soundex.end(), '.'), soundex.end());

    if (soundex.length() < 4)
    {
        soundex.append(4 - soundex.length(), '0');
    }
    else if (soundex.length() > 4)
    {
        soundex = soundex.substr(0, 4);
    }

    return boost::hash_value(soundex);
}

int main()
{
    std::cout << "Color = " << SoundexHash("Color") << std::endl;
    std::cout << "Colour = " << SoundexHash("Colour") << std::endl;

    std::cout << "Gray = " << SoundexHash("Gray") << std::endl;
    std::cout << "Grey = " << SoundexHash("Grey") << std::endl;

    return 0;
}
于 2011-06-26T13:46:12.317 に答える