Levenshtein算法:如何满足此文本编辑要求?

时间:2009-01-27 19:27:26

标签: c++ algorithm pattern-matching levenshtein-distance

我正在使用levenshtein算法来满足这些要求:

当找到N个字符的单词时,在我的字典数据库中建议更正的单词是:

N个字符的每个字典单词,与找到的单词有1个不同的字符。 例: 发现单词:bearn,字典单词:bears

N + 1个字符的每个字典单词,其N个字符等于找到的单词。 例: 发现词:熊,字典词:熊

N-1个字符的每个字典单词,其N-1个字符等于找到的单词。 例: 发现词:熊,字典词:熊

我在C ++中使用Levenshtein算法的这种实现来查找一个单词的Levenshtein数为1(这是所有三个案例的Levenshtein数),但是我该如何选择这个单词?我读到了Boyer-Moore-Horspool和Knuth-Morris-Pratt,但我不确定他们中的任何一个是如何有用的。

#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int levenshtein(const string &s1, const string &s2)
{
   string::size_type N1 = s1.length();
   string::size_type N2 = s2.length();
   string::size_type i, j;
   vector<int> T(N2+1);

   for ( i = 0; i <= N2; i++ )
      T[i] = i;

   for ( i = 0; i < N1; i++ ) {
      T[0] = i+1;
      int corner = i;
      for ( j = 0; j < N2; j++ ) {
         int upper = T[j+1];
         if ( s1[i] == s2[j] )
            T[j+1] = corner;
         else
            T[j+1] = min(T[j], min(upper, corner)) + 1;
         corner = upper;
      }
   }
   return T[N2];
}

4 个答案:

答案 0 :(得分:6)

您可能还想在阅读中添加Norvig's excellent article on spelling correction

我读过它已经有一段时间了,但我记得它与你的写作非常相似。

答案 1 :(得分:2)

正如我在其他地方所说的那样,Boyer-Moore并不适合这一点。既然你想同时搜索多个蜇,那么Wu和Manber的算法应该更符合你的喜好。

我在another question的回答中发布了概念验证C ++代码。注意那里提到的警告。

答案 2 :(得分:0)

为什么要将建议限制在单个单词中,为什么不包含一组单词?如果您只能使用一个单词,则可以按照预先计算的使用频率或某事来订购结果。可以根据用户从建议中选择的内容更新此频率。

此外,在原始单词中没有拼写错误的情况下,您可能希望优先处理N + 1个案例,这更像是自动完成。无论如何,我认为没有一种正确的方法可以做到这一点,也许如果你的要求更具体,那就更容易缩小范围。

此外,您无需了解Python即可理解Norvig文章中描述的算法。

答案 3 :(得分:0)

如果我理解正确,那么你的问题就没有正确答案。您正在使用Levenshtein为给定单词识别最多三个建议 - 您需要制定一个规则来决定使用哪个以及要过滤掉哪个。或许你应该全部使用它们?

正如感兴趣一样,Damerau对Levenshtein的扩展可能会引起你的兴趣,其中两个交换的角色也被认为得分为1而不是2,这是香草Levenshtein回归的。