【问题标题】:What's the size of a prefix tree (trie) that contains all the english words?包含所有英文单词的前缀树(trie)的大小是多少?
【发布时间】:2014-03-04 21:04:23
【问题描述】:

知道英语词典中大约有 200k 个单词,而字母表有 26 个左右的字母。

【问题讨论】:

  • 您的估价偏低。根据Oxford Dictionaries 网站,有至少 25 万个英语单词,这还不包括字典不跟踪的技术单词。

标签: data-structures trie


【解决方案1】:

this article 中,作者从一个 935,015 字节长的文件中构建了一个英语单词 trie。它需要 25 万个节点。他声称压缩率约为 73%,这与我在使用此类数据结构时所记得的非常接近。

请注意,他的实现通过为每个节点存储一个包含 26 个子指针的数组来浪费大量内存。一个更便宜的实现将只维护它需要的指针,按使用频率排序。例如,考虑到q 之后的字符除了u 之外的其他字符非常,在一个单词中存储字母q 的26 个子节点指针有点疯狂。

顺序搜索比直接索引数组花费的时间稍长,但可以节省大量内存。而且节省的内存可以减少很多缓存未命中,这完全可以弥补线性搜索增加的成本。

如果您对节省更多空间感兴趣,可以创建一个有向无环词图,它还利用了常见的结尾以及其他一些优化。例如,您可以将悬空结尾压缩到单个节点中。

【讨论】:

    【解决方案2】:

    使用简单的前缀树,空间要求应该是 O(N*C),其中 C 是每个单词的平均字符数,N 是单词数。这是因为在最坏的情况下,Trie 将存储每个单词中的每个字符。因此,公平的估计是存储了大约 100 万个字符,或大约 1 MB。

    【讨论】:

    • 你有这方面的参考吗?一个包含 600,000 个英文单词的 trie 将存储的节点数量远远少于 600,000 个。可以肯定的是,我知道“cat”一词的商店“c”、“ca”和“cat”。我认为您需要阅读什么是 trie 以及它是如何存储的。 en.wikipedia.org/wiki/Trie
    • 确实,我正在考虑一种用于子字符串搜索的更复杂的数据结构,它基于 Trie。虽然,这也可能是 O(NC),但现在我考虑了一下。在这种情况下,只有 O(NC),其中 C 是平均字符数,而且很高。
    • 是的。 (N*C) 是最坏的情况,只有在没有公共前缀的情况下才会发生。
    • 我说过,600,000 个英文单词的 trie 将存储少于 600,000 个节点。我的意思是总共有 600,000 个字符组成单词。
    • 鉴于平均字符数是常数,字符数和单词数都是O(N)。所以我知道你的意思,即使我没有发现错误。我几乎看到了 600,000 两次,浏览了您的答案,然后转到您提供的链接以更详细地查看它。
    【解决方案3】:

    Wolfram alpha 表示单词的平均长度为 5.1 个字符 http://www.wolframalpha.com/input/?i=average+english+word+length

    如果 L=26,字母表中的字母数 而K=5.1 一个英文单词的平均长度

    => 我希望空间复杂度在 O(L^K) 左右 (L 到 K 次幂)

    我想,实际语言的实现可能会有所不同。

    【讨论】:

    • 您的估计似乎没有根据。 L^K 是具有 L 符号字母表的所有 K 长度字符串的数量,即它可能估计的唯一相关数字是存在的 单词数,但这已经给出,它不是我们试图找到的数量。此外,即使出于这个目的,它也是错误的,无论是在理论上(它计算所有可能的字符串,其长度与普通英语单词的长度相同,但其中大多数不是英语单词,而且许多英语单词的长度不同)和实践中(它提供了大约 88 亿而不是 20 万)。
    • 除了@delnan 的反对意见之外,L^K 数字假定没有公共前缀。前缀树的全部意义在于利用公共前缀。快速搜索显示从(N*K)/4(N*K)/3 节点的经验结果,其中N 是单词数,K 是单词的平均长度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    • 2020-02-18
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多