【问题标题】:Complexity in using Binary search and Trie使用二分查找和 Trie 的复杂性
【发布时间】:2011-02-12 17:06:09
【问题描述】:

给定文件中按字母顺序排序的大量单词列表,我需要编写一个程序,给定单词 x,确定 x 是否在列表中。预处理没问题,因为我将通过不同的输入多次调用此函数。
优先事项: 1.速度。 2. 记忆

我已经知道我可以使用(n 是单词数,m 是单词的平均长度) 1.一个trie,时间是O(log(n)),空间(最好情况)是O(log(nm)),空间(最坏情况)是O(nm)。 2.将完整列表加载到内存中,然后进行二分查找,时间为O(log(n)),空间为O(n*m)

我不确定 tri 的复杂性,如果他们错了,请纠正我。还有其他好的方法吗?

【问题讨论】:

    标签: algorithm data-structures complexity-theory


    【解决方案1】:

    trie 的时间为 O(m),二分查找的时间为 O(mlog(n))。对于任何合理的方法,空间都是渐近 O(nm) 的,在某些情况下您可以使用压缩来减少它。从理论上讲,trie 结构在内存方面要好一些,但实际上它隐藏在实现细节中的魔鬼:存储指针所需的内存和潜在的不良缓存访问。

    还有其他实现集合结构的选项 - hashset 和 treeset 在大多数语言中都是简单的选择。我会选择散列集,因为它既高效又简单。

    【讨论】:

    • 是的,散列集可能是最好的。我担心内存消耗。但我想在任何方法中,内存都是 O(N*M)?本来打算用特里的,现在你把我吓跑了。在太空中不是渐近更好吗?
    • 这取决于很多细节。例如。您可以注意到,trie 的空间要求也可以受 a^m 之类的限制(其中 a 是字母的大小),在某些玩具示例中,它可能小于 n*m。然而,对于足够长的字符串的足够大数据集,存储 trie 并不比仅逐字存储字符串更有效。因此,如果您有大量的长字符串,您最好将它们存储在一些智能逐字但压缩的形式中,并使用哈希集作为此结构的索引。
    【解决方案2】:

    我认为 HashMap 非常适合您的情况,因为 put 和 get 操作的时间复杂度都是 O(1)。即使您没有排序列表,它也能正常工作。!!!

    【讨论】:

    • 不,不是:计算字符串的哈希是 O(​​m),所以使用 HashMap 是 O(m)。理论上它比 Trie 更糟糕,因为如果字符串不在 trie 中,则算法不必解析所有字母。
    • 是的,但我仍然认为如果您有大量单词列表,这种方式会更好,因为 m 会比 n 少得多。
    【解决方案3】:

    预处理没问题,因为我将多次调用此函数 输入。

    作为思考的食物,您是否考虑从输入数据创建一个集合,然后使用特定的哈希进行搜索?第一次构建集合需要更多时间,但如果输入数量有限并且您可以返回到它们,那么集合可能是一个好主意,使用 O(1) 进行“包含”操作以获得良好的哈希函数。

    【讨论】:

      【解决方案4】:

      我会推荐一个哈希图。您可以在 VC 和 GCC 中找到 C++ 的扩展。

      【讨论】:

        【解决方案5】:

        使用布隆过滤器。即使对于非常大的数据,它也很节省空间,而且它是一种快速的拒绝技术。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-01-31
          • 1970-01-01
          • 2012-01-01
          • 1970-01-01
          • 2022-08-11
          • 2012-03-16
          • 2021-08-25
          相关资源
          最近更新 更多