在实施伴有单词建议的拼写检查程序时,通常使用什么算法?
起初我认为从字典中的每个其他单词检查每个键入的新单词(如果没有在字典中找到)可能是有意义的,并且返回顶部结果。Levenshtein distance然而,这似乎非常低效,不得不反复评估整个字典。
这通常是如何完成的?
答案 0 :(得分:193)
good essay by Peter Norvig如何实施拼写纠正器。它基本上是一种蛮力方法,尝试使用给定编辑距离的候选字符串。 (Here是如何使用Bloom Filter和faster candidate hashing提高拼写纠正器效果的一些提示。)
拼写检查程序的要求较弱。你只需要发现一个单词不在字典中。您可以使用Bloom Filter构建一个消耗较少内存的拼写检查程序。 Jon Bentley使用64kb作为英语词典,在Programming Pearls中描述了古代版本。
Levenshstein距离不是拼写检查器的正确编辑距离。它只知道插入,删除和替换。缺少转置,并为1个字符的转置产生2(它是1个删除和1个插入)。 Damerau–Levenshtein distance是正确的编辑距离。
答案 1 :(得分:17)
用于生成我已经成功使用但从未在任何地方看到的建议的方法是使用“坏”散列函数预先计算建议(在构建字典时)。
我们的想法是查看人们所犯的拼写错误类型,并设计散列函数,将错误拼写分配给与正确拼写相同的存储桶。
例如,常见的错误是使用错误的元音,例如 definate 而不是明确的。因此,您设计了一个哈希函数,将所有元音视为相同的字母。一种简单的方法是首先“标准化”输入字,然后通过常规散列函数将标准化结果放入。在此示例中,规范化功能可能会删除所有元音,因此definite
变为dfnt
。然后使用典型的散列函数对“规范化”字进行散列。
使用此特殊哈希函数将所有词典单词插入辅助索引(哈希表)。此表中的存储桶将具有较长的冲突列表,因为哈希函数是“坏”的,但这些冲突列表基本上是预先计算的建议。
现在,当您找到拼写错误的单词时,您将查找拼写错误映射到辅助索引中的存储桶的冲突列表。塔达:你有一个建议清单!您所要做的就是对其中的单词进行排名。
在实践中,你需要一些带有其他哈希函数的辅助索引来处理其他类型的错误,比如转置字母,单/双字母,甚至是一个简单的类似Soundex的错误来捕捉拼音错误拼写。在实践中,我发现简单的发音有很长的路要走,并且基本上废除了一些旨在找到琐碎错别字的发音。
所以现在你在每个辅助索引中查找拼写错误并在排名之前连接碰撞列表。
请记住,碰撞列表仅包含字典中的单词。通过尝试生成替代拼写的方法(如Peter Norvig文章中所述),您可以获得(数十)数千个候选人,首先必须对字典进行过滤。使用预先计算的方法,你可能会得到几百名候选人,并且你知道他们都拼写正确,所以你可以直接跳到排名。
更新:我发现了一个与此类似的算法描述FAROO Distributed Search。这仍然是一个编辑距离限制搜索,但它非常快,因为预计算步骤就像我的“坏哈希函数”的想法。 FAROO只使用了有限的哈希函数概念。
答案 2 :(得分:6)
答案 3 :(得分:3)
您无需知道字典中每个单词的确切编辑距离。您可以在达到限制值后停止算法并排除该单词。这将为您节省大量的计算时间。
答案 4 :(得分:1)
拼写检查程序非常容易实现,就像Unix拼写程序一样。源代码公开发布。可以涉及校正,一种技术是进行编辑并再次检查这个新单词是否在字典中。这些新编辑可以分组并显示给用户。
Unix系统使用Mc IllRoy编写的程序。另一种方法是使用Trie,这对于大文件来说非常有用。
unix方法对于庞大的字典需要的空间非常少,因为它使用了散列散列算法。