【问题标题】:Numerical hash for comparing lexical similarity用于比较词汇相似性的数字哈希
【发布时间】:2011-06-26 13:25:43
【问题描述】:

是否有某种形式的散列算法可以为相似的词产生相似的数值?我想会有很多误报,但这似乎对搜索修剪有用。

编辑:Soundex 很简洁,可能会派上用场,但理想情况下,我想要这样的东西:abs(f('horse') - f('hoarse')) < abs(f('horse') - f('goat'))

【问题讨论】:

  • @Cicada,你能提交这个作为答案吗?即使没有我想要的语言的实现,这正是我正在寻找的。​​span>

标签: search text hash pruning


【解决方案1】:

Soundex 算法生成与输入单词中的音素相对应的键字符串。 http://www.archives.gov/research/census/soundex.html

如果您只想比较字符串之间的相似性,请尝试 Levenstein Distance。 http://en.wikipedia.org/wiki/Levenshtein_distance

【讨论】:

【解决方案2】:

你所说的叫Locality-sensitive Hashing。它可以应用于不同类型的输入(图像、音乐、文本、空间位置,任何你需要的)。

不幸的是(尽管搜索)我找不到任何实际的字符串 LSH 算法实现。

【讨论】:

    【解决方案3】:

    您可以随时尝试Soundex,看看它是否符合您的需求。

    【讨论】:

      【解决方案4】:

      查看 wikipedia 上的 Soundex 算法,您没有指定语言,但那里有多种语言的示例实现链接。显然,这将为您提供一个与发音相似的单词相同的字符串哈希,并且您需要一个整数,但您可以应用他们在Boost.Hash 中使用的字符串->整数哈希方法。

      编辑:为了澄清,这里是一个示例 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-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-26
        • 2021-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多