C++ C++;(Hashmap样式)数据结构是否适合此场景?
人们对各种数据结构的效率提出了类似的问题,但我所读到的没有一个完全适用于我的场景,因此我想知道人们是否对一种能够有效满足以下标准的数据结构提出了建议:C++ C++;(Hashmap样式)数据结构是否适合此场景?,c++,data-structures,hash,C++,Data Structures,Hash,人们对各种数据结构的效率提出了类似的问题,但我所读到的没有一个完全适用于我的场景,因此我想知道人们是否对一种能够有效满足以下标准的数据结构提出了建议: 每个元素都有一个唯一的键。由于每个元素散列到不同的键,因此不存在冲突的可能性编辑:*密钥是32位uint。* 这些元素都是唯一的,因此可以将其视为一个集 唯一需要的操作是添加和获取,而不是删除。这些需要很快,因为它们将在一次典型运行中使用100000次 元素的保存顺序是不相关的 速度比内存消耗更重要。。。虽然不能太多 贪婪 我正在为一家将在商
- 每个元素都有一个唯一的键。由于每个元素散列到不同的键,因此不存在冲突的可能性编辑:*密钥是32位uint。*
- 这些元素都是唯一的,因此可以将其视为一个集李>
- 唯一需要的操作是添加和获取,而不是删除。这些需要很快,因为它们将在一次典型运行中使用100000次李>
- 元素的保存顺序是不相关的李>
- 速度比内存消耗更重要。。。虽然不能太多 贪婪李>
你所需要的肯定听起来像是一个哈希集,C++有这个作为“代码> STD:::Tr1::unOrdEdset set < /Cost >或升压。无序。
然而,请注意,TR1还不是标准的,您可能需要为实现得到提升。听起来像是
std::unordered\u set
符合要求,但没有
了解更多关于钥匙的知识,这很难说。我很好奇
如何保证不会发生碰撞:
这意味着一个小的(小于表的大小)有限的
钥匙。如果是这种情况,将密钥映射到
一个小的int,并使用std::vector
(对于非
当前)。看起来前缀树(每个节点端都有元素)也适用于此场景。它非常快,甚至比hash-map还要快,因为没有进行hash值计算,获取值纯粹是O(n),其中n是密钥长度。这有点内存不足,但密钥的公共前缀在同一节点路径中共享
编辑:我假设键是字符串,而不是像整数这样的简单值,对于内置解决方案,我建议使用google::dense\u hash\u map。它们非常快,尤其是数字键。您必须决定保留为“空密钥”的特定密钥。此外,这里是一个非常好的不同的哈希映射实现 摘录
Library Linux-intCPU (sec) Linux-strCPU (sec) Linux PeakMem (MB)
glib 3.490 4.720 24.968
ghthash 3.260 3.460 61.232
CC’s hashtable 3.040 4.050 129.020
TR1 1.750 3.300 28.648
STL hash_set 2.070 3.430 25.764
google-sparse 2.560 6.930 5.42/8.54
google-dense 0.550 2.820 24.7/49.3
khash (C++) 1.100 2.900 6.88/13.1
khash (C) 1.140 2.940 6.91/13.1
STL set (RB) 7.840 18.620 29.388
kbtree (C) 4.260 17.620 4.86/9.59
NP’s splaytree 11.180 27.610 19.024
但是,当设置“已删除的_键”时,此映射也可以执行删除。因此,也许可以创建一个更高效的定制解决方案。但除了这一小点之外,任何哈希映射都应该完全符合您的需要(请注意,“map”是一个有序的树映射,因此速度较慢)。您要查找的是一个
无序集。您可以在Boost、TR1或C++0x中找到一个。如果您希望将键与值关联,那么unordered_map
就是这样做的-在Boost/TR1/C++0x中也是如此。使用普通的std::map有什么问题吗?我认为您想得太多了。我会选择散列图@map使用红黑树,根据上面的描述,我认为哈希表更合适。您将存储多少个元素(大约)?你会重复地添加和获取,还是添加元素然后获取它们?当你说taht时,顺序是不相关的:你总是按顺序访问还是按键访问?你对钥匙以及钥匙是如何构造的有什么了解吗?@John Paul我想知道哪一种最有效、最合适。你是说map是吗?@Mario The Spoon键是uint,我用键检索值,然后在执行结束时遍历表中的所有条目。非常感谢你的输入。我已经更新了关于钥匙的问题,这是一个uint。它们是唯一的,因为我将查找散列值,如果它已经存在于表中,我只使用存储的值,而不是新值。没有涉及线性探测或链接,因为这是不必要的。@温室气体如果您可以创建一个足够大的std::vector
来容纳所有可能的条目,直接使用uint
将是最快的解决方案。但是,如果uint
的范围不受限制,则必须将[0…uint\u MAX]
映射到表的大小,这意味着要处理冲突。对std::unordered_set
的任何改进都必须基于实际中密钥分布的知识。O(n)?你确定吗?hash映射是O(1),二叉树是O(logN),因此O(n)在比较中似乎并不快…@juanchopanza但您的数量级注释是以集合的大小为基础的,而这里的n是关键长度如果您使用的是一个合理的新gcc,那么您可以访问无序映射和g++-std=c++0x