Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java trie实现中的空间差异_Java_String_Algorithm_Data Structures_Trie - Fatal编程技术网

Java trie实现中的空间差异

Java trie实现中的空间差异,java,string,algorithm,data-structures,trie,Java,String,Algorithm,Data Structures,Trie,我读得越多,出于某种原因我就越困惑。 现在让我困惑的是: 我已经读过两种类型的实现 使用数组表示字符(不存储字符 并且在每个节点中还存储实际单词的索引(如果 我们达成了协议) 使用存储字符和结尾的节点的集合 对于每个节点,使用一个布尔值来确定是否到达一个单词 沿着这条路走 在第一种情况下,它没有被提及,但似乎我们实际上必须保留所有字典中的单词(因为我们间接引用它们)。因此我们处理了数组大小*numberOfNodes*lengthOfword+字典大小 在后一种情况下,我们不需要字典,因为字符直

我读得越多,出于某种原因我就越困惑。
现在让我困惑的是:
我已经读过两种类型的实现

  • 使用数组表示字符(不存储字符 并且在每个节点中还存储实际单词的索引(如果 我们达成了协议)
  • 使用存储字符和结尾的节点的
    集合
    对于每个节点,使用一个布尔值来确定是否到达一个单词 沿着这条路走
  • 在第一种情况下,它没有被提及,但似乎我们实际上必须保留所有字典中的单词(因为我们间接引用它们)。因此我们处理了
    数组大小*numberOfNodes*lengthOfword+字典大小

    在后一种情况下,我们不需要字典,因为字符直接存储在树中。因此,在我看来,第二种实现更节省空间。但我不确定具体是多少。

    我对实现的理解正确吗?是否有具体的理由选择其中一个?另外,我们如何计算第二种情况下的空间需求?

    尝试不将原始单词存储在任何位置,而是隐式存储它们。trie的基本结构如下:trie中的每个节点存储

    • 确定到达节点的路径是否形成字的单个位,以及
    • 指向由字符标记的子节点的指针集合
    要确定一个单词是否在trie中,可以从根开始,然后按照适当标记的指针一次一个进行操作。如果到达标记为单词的节点,则该单词存在于trie中。如果到达未标记的节点或从trie上掉下来,则该单词不存在

    上面列出的两种结构之间的区别在于子指针的存储方式。在第一个版本中,子指针存储为字母表中每个符号一个指针的数组,这使得后面的子指针非常快,但空间效率非常低。在第二个版本中,显式存储某种类型的集合,其中只包含所需的标记指针。这速度较慢,但对于稀疏尝试来说更节省空间

    trie的空间使用取决于节点的数量(称为n)、字母表的大小(称为k)以及子指针的表示方式。如果存储一个固定大小的指针数组,则空间使用量约为kn指针(n个节点,每个节点有k个指针),加上每个节点上标记的n位。例如,如果您有一个按排序顺序存储的指针动态数组,那么开销将是n个子指针总数,加上n位,再加上存储单个集合所需的n倍空间

    第一种方法的优点是速度快、简单,在密集的尝试中具有很好的性能。第二种方法速度较慢,但对于稀疏尝试来说内存效率更高

    这些并不是唯一可能的空间优化。Patricia尝试将只有一个子节点的节点压缩在一起,并且非常节省空间。DAWG尝试将尽可能多的节点合并在一起,但不支持有效的插入


    希望这有帮助

    1)实际单词中的索引如何?这种方法是由Sedgewick提出的。2)为什么第二种方法较慢?在一个大小不变的集合上迭代集合以查找是否存在子项。字母表大小。访问时间不是恒定的吗?3)我不知道存储的动态指针数组是什么意思按排序顺序,1。我以前从未在书里看到过单词索引;如果您想为每个节点存储辅助数据,这可能会很有用,但这肯定不是必需的。2.虽然第二种方法也可以在常数时间内找到子对象,但它是一个更大的常数。您必须在指针集合上进行二进制搜索或线性搜索才能找到所需的指针,而基于数组的版本需要单个间接寻址。3.我建议将子指针存储在一个动态分配的数组中,指针按使用的字符升序排列。这有帮助吗?@Cratylus-看我上面的回答。你的意思是让集合中的字符保持排序?这不会增加插入时间吗?内部单词的索引由Sedgewick提供。不确定他是否解决了其他问题approach@Cratylus-保持排序是一种折衷——它减少了查找时间(二进制搜索),但会增加插入时间。没有一种“最佳方法”可以实现trie。每件事都是一种折衷,而这只是一个什么折衷对你最有利的问题。所展示的大多数用于尝试的示例都可以通过其他方式更有效地实现(Wikipedia示例使用哈希字典提供字符查找,尤其糟糕)。在更大范围的查找表中,例如,单个单词是节点键的查找表中,尝试提供明显的胜利。它们还可以为稀疏表提供一个赢家。