用于构建快速拼写检查器的高效数据结构


41

我正在尝试编写一个拼写检查器,该检查器应与相当大的词典一起使用。我真的想要一种有效的方法来索引我的字典数据,该数据将使用Damerau-Levenshtein距离来确定哪些单词最接近拼写错误的单词。

我正在寻找一种数据结构,该结构将在空间复杂度和运行时复杂度之间取得最佳折衷。

根据我在互联网上发现的信息,我对使用哪种类型的数据结构有一些建议:

特里

trie-500px

这是我的第一个想法,看起来很容易实现,应该提供快速的查找/插入。使用Damerau-Levenshtein进行的近似搜索在此处也应易于实现。但是就空间复杂度而言,它看起来不是很有效,因为指针存储很可能会带来很多开销。

帕特里夏·特里(Patricia Trie)

trie-500px

这似乎比常规的Trie占用更少的空间,因为您基本上避免了存储指针的成本,但是对于像我一样的非常大的字典,我有点担心数据碎片。

后缀树

后缀500px

我不确定这一点,似乎有些人确实发现它在文本挖掘中很有用,但是我真的不确定它对于拼写检查器的性能会有什么帮助。

三元搜索树

tst

这些看起来不错,并且在复杂性方面应该与Patricia Tries接近(更好?),但是我不确定碎片是否比Patricia Tries更好。

爆裂树

爆

这似乎是一种混合,我不确定它比Tries等具有什么优势,但是我已经读过好几次了,它对于文本挖掘非常有效。


我想就哪种数据结构最适合在这种情况下使用以及什么使它比其他结构更好的问题得到一些反馈。如果我缺少一些更适合拼写检查的数据结构,我也很感兴趣。


patricia trie如何避免存储指针的成本?仅仅是en.wikipedia.org/wiki/Radix_tree吗?如果真是这样,那么我认为它仍然可以存储很多指针,但是您将节省大量空间,因为公共前缀仅存储一次
Joe

没有细节,您要求的比较可能是不可能的。特别是,您的字典的密度是多少?您要检测到多大的拼写错误(您似乎说的是无限的)?字典+变体的密度是多少?(这里的密度是指存储在存储集中的所有长度为单词的分数。)n
拉斐尔

1
@linker:您是否尝试过字典的所有变体?给定固定的用例,这可能是找出哪个数据结构消耗多少空间的最快方法。
拉斐尔

1
它只是一本基本的字典,只是已知的正确拼写单词的列表。
Charles Menguy

Answers:


4

我遇到了相同的问题,但是采用了不同的方法。您可以构造某种“哈希”函数,对于相似的单词,该函数将给出相同或相近的数字。

问题是,该函数将为插入/删除的单词提供“好”结果,为过渡提供“差”,反之亦然。例如:将字母映射到数字,将相似的字母映射到相邻的数字,然后对单词中的每个字母求和。然后创建带有每个键集的哈希表,并找到单词的交集。

如果我们看单词的“空格”,可能会取得一些结果。X用于更改字母,Y用于添加/删除,Z用于过渡,等等。

但是,这只是抽象的想法,我没有足够的时间来实现它们。


这就是Soundex的工作en.wikipedia.org/wiki/Soundex
rgrig

4

如果无法使用蛮力,则可能要使用度量树进行快速研究(始终尝试蛮力)。在可以找到您的邻居,但是的常数可能很大。您似乎有数百万个字符串,所以这可能是一个不错的权衡。O(log(n))O

不要将字符串存储在度量标准树中。只需存储一个索引,然后将字符串存储在Patricia树中即可。

我不确定您应该使用哪棵树。这将取决于您的数据和要求(是否需要快速插入?)。如果您发现一棵树比另一棵树更有效率,请更新您的问题。

您还可以查看专门的工具,例如lucene。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.