【问题标题】:What is an efficient search algorithm to provide auto-completion?什么是提供自动完成的有效搜索算法?
【发布时间】:2010-02-25 06:12:10
【问题描述】:

我有一个包含 10000 个关键字的列表。为该列表提供自动完成功能的有效搜索算法是什么?

【问题讨论】:

    标签: algorithm search


    【解决方案1】:

    使用Trie 是一种选择,但它们的空间效率很低。通过使用称为 Radix Tree 或 Patricia Tree 的修改版本,它们可以更加节省空间。

    三元搜索树可能是更好的选择。这是一篇关于这个主题的文章:“Efficient auto-complete with a ternary search tree.”另一篇关于使用三元搜索树进行拼写纠正(与自动完成类似的问题)的优秀文章是“Using Ternary DAGs for spelling correction.

    【讨论】:

    • 请注意,不是在 Trie 的每个节点中都有一个固定大小的数组,而是可以只存储一个动态大小的数组,为每个添加的不存在的字母扩展它(链表? )
    【解决方案2】:

    我认为 binary search 对于 10000 个条目来说效果很好。

    【讨论】:

      【解决方案3】:

      特里:http://en.wikipedia.org/wiki/Trie 给你 O(N) 的搜索时间,只要你输入一个字母(我假设你在输入一个字母时需要新的建议)。如果您的单词很小,这应该是相当有效的,并且每个新字母都会减少搜索空间。

      【讨论】:

        【解决方案4】:

        正如您已经提到的,您将单词存储在数据库中(请参阅Auto-suggest Technologies and Options),创建该单词的索引并让数据库完成工作。他们知道如何有效地做到这一点。

        【讨论】:

          【解决方案5】:

          在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 个字母的单词(触发自动完成的经典阈值),速度似乎也不错:

          • 在哈希图中查找 3 次
          • 2 个集合的交集(绝对是一个点),但要尽可能高效地排序。

          我肯定需要在三叉树上尝试一下,然后尝试这种方法,看看效果如何。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-19
            • 1970-01-01
            • 2021-12-03
            相关资源
            最近更新 更多