我有10000个关键字的列表。什么是有效的搜索算法,以提供该列表的自动完成?
答案 0 :(得分:6)
使用Trie是一种选择,但它们的空间效率低。通过使用称为Radix Tree或Patricia Tree的修改版本,可以使它们更具空间效率。
三元搜索树可能是更好的选择。这是一篇关于这个主题的文章:“Efficient auto-complete with a ternary search tree.”另一篇关于使用三元搜索树进行拼写校正(类似于自动完成的问题)的优秀文章是“Using Ternary DAGs for spelling correction.”
答案 1 :(得分:4)
我认为binary search适用于10000个条目。
答案 2 :(得分:3)
一个特里:http://en.wikipedia.org/wiki/Trie只要你输入一个字母就给你O(N)搜索时间(假设你输入一个字母时我想要新的建议)。如果你的单词很小,那么这应该是相当有效的,并且每个新字母的搜索空间都会减少。
答案 3 :(得分:0)
正如您已经提到的那样,您将单词存储在数据库中(请参阅Auto-suggest Technologies and Options),创建该单词的索引并让数据库完成工作。他们知道如何有效地做到这一点。
答案 4 :(得分:0)
针对填字游戏提出了一种相当迂回的方法。
这可以很容易地适应:)
这个想法很简单,但效率很高:它包括索引单词,为每个字母位置构建一个索引。应该注意的是,在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个字母的单词(经典阈值来触发自动完成):
我肯定需要尝试对抗三元树和trie方法,看看它的票价。