用于在存储器中存储字符串数组的数据结构

时间:2010-08-29 21:39:12

标签: c++ string data-structures std

我正在考虑在内存中存储大量字符串的数据结构。字符串将在程序开头插入,并且在程序运行时不会添加或删除。关键的一点是搜索程序应该尽可能快。节省内存并不重要。我倾向于标准库中的标准结构hash_set,它允许以大约恒定的时间搜索结构中的元素。但这并不能保证这个时间很短。有人会建议更好的标准决定吗?

非常感谢!

7 个答案:

答案 0 :(得分:3)

尝试Prefix Tree

Trie比二叉搜索树更适合搜索元素。与哈希表相比,您可以看到this question

答案 1 :(得分:2)

如果查找时间确实是唯一重要的事情,那么在启动时,一旦拥有了所有字符串,就可以计算perfect hash,并将其用作散列表的散列函数。

问题在于你如何执行散列 - 任何类型的基于字节码的计算可能比使用固定散列和处理冲突要慢。但是,如果您关心的只是查找速度,那么您可以要求您的进程具有加载和执行代码所需的权限。编写完美哈希的代码,通过编译器运行,加载它。在运行时测试这些字符串实际上是否比您最熟知的数据无关结构(可能是Trie,哈希表,Judy数组或splay树,实际上更快,具体取决于实现细节和典型访问模式),如果没有回归。设置缓慢,快速查找。

速度是唯一关键点几乎不是真正的情况。

答案 2 :(得分:1)

例如google-sparsehash。 它包括密集的散列集/映射(重新)实现,其可能比标准库散列集/映射更好地执行。 见performance。确保使用良好的哈希函数。 (我的主观投票:murmur2。)

  

将插入字符串   程序的开头并不会   在程序运行时添加或删除。

如果字符串是不可变的 - 所以插入/删除是“不常见的”,可以这么说 - 另一种选择是建立一个{sup} * Directed Acyclic Word Graph或Compact Directed Acyclic Word Graph >比哈希表更快,并且有更好的最坏情况保证。

**标准免责声明适用:取决于使用案例,实施,数据集,月相等。理论预期可能与观察结果不同,因为未考虑的因素(例如缓存和内存延迟,某些机器指令的时间复杂度等。)*。

答案 3 :(得分:0)

具有适当数量的桶的hash_set将是理想的,或者具有字典顺序的字符串的向量,搜索使用的二进制搜索,也将是很好的。

答案 4 :(得分:0)

好吧,假设你真的想要一个数组而不是你所提到的关联容器Raymond Chen's Blog中提到的分配策略会很有效。

答案 5 :(得分:0)

快速字符串查找的两个标准数据结构是哈希表和tries,尤其是Patricia tries。只要哈希实现足以限制冲突的数量,良好的哈希实现和良好的trie实现应该提供类似的性能。由于您从不修改字符串集,因此您可以尝试构建perfect hash。如果性能比开发时间更重要,请尝试所有解决方案并对其进行基准测试。

可以在字符串表中保存查找的补充技术是使用 atoms :每次读取一个你知道要在表中查找的字符串时,立即查找,并存储指向它的指针(或数据结构中的索引),而不是存储字符串。这样,测试两个字符串的相等性是一个简单的指针或整数相等(你也可以通过存储每个字符串一次来节省内存)。

答案 6 :(得分:0)

您最好的选择如下:

  1. 构建您的结构:
    1. 将所有字符串(char * s)插入数组中。
    2. 按字典顺序排列数组。
  2. 查找
    1. 在阵列上使用二进制搜索。
  3. 这维护了缓存局部性,允许有效查找(将在大约40亿个字符串的空间中进行32次比较),并且实现起来很简单。没有必要尝试尝试,因为它们很复杂,并且比它们出现的速度慢(特别是如果你有长串)。

    随机旁注:结合http://blogs.msdn.com/b/oldnewthing/archive/2005/05/19/420038.aspx,你将无法阻挡!