【发布时间】:2010-02-25 06:12:10
【问题描述】:
我有一个包含 10000 个关键字的列表。为该列表提供自动完成功能的有效搜索算法是什么?
【问题讨论】:
我有一个包含 10000 个关键字的列表。为该列表提供自动完成功能的有效搜索算法是什么?
【问题讨论】:
使用Trie 是一种选择,但它们的空间效率很低。通过使用称为 Radix Tree 或 Patricia Tree 的修改版本,它们可以更加节省空间。
三元搜索树可能是更好的选择。这是一篇关于这个主题的文章:“Efficient auto-complete with a ternary search tree.”另一篇关于使用三元搜索树进行拼写纠正(与自动完成类似的问题)的优秀文章是“Using Ternary DAGs for spelling correction.”
【讨论】:
我认为 binary search 对于 10000 个条目来说效果很好。
【讨论】:
特里:http://en.wikipedia.org/wiki/Trie 给你 O(N) 的搜索时间,只要你输入一个字母(我假设你在输入一个字母时需要新的建议)。如果您的单词很小,这应该是相当有效的,并且每个新字母都会减少搜索空间。
【讨论】:
正如您已经提到的,您将单词存储在数据库中(请参阅Auto-suggest Technologies and Options),创建该单词的索引并让数据库完成工作。他们知道如何有效地做到这一点。
【讨论】:
在SO上提出了一种相当迂回的填字游戏方法。
它可以很容易地适应这里:)
这个想法很简单,但非常有效:它包括对单词进行索引,每个字母位置建立一个索引。应该注意的是,在 4/5 个字母之后,可用的单词子集是如此之小,以至于蛮力可能是最好的……这当然必须测量。
至于思路,这里是Python方式:
class AutoCompleter:
def __init__(self, words):
self.words = words
self.map = defaultdict(set)
self._map()
def _map(self):
for w in words:
for i in range(0,len(w)):
self.map[(i,w[i])].insert(w)
def words(self, firstLetters):
# Gives all the sets for each letter
sets = [self.map[(i, firstLetters[i])] for i in range(0, len(firstLetters))]
# Order them so that the smallest set is first
sets.sort(lambda x,y: cmp(len(x),len(y)))
# intersect all sets, from left to right (smallest to biggest)
return reduce(lambda x,y: intersection(x,y), sets)
内存要求非常严格:每个位置的每个字母一个条目。但是,一个条目意味着一个单词在这个位置存在一个字母,并非所有情况都如此。
如果您希望自动完成一个 3 个字母的单词(触发自动完成的经典阈值),速度似乎也不错:
我肯定需要在三叉树上尝试一下,然后尝试这种方法,看看效果如何。
【讨论】: