不确定无序映射是如何工作的
Not sure how unordered_map works
我有点困惑无序映射是如何工作的,什么是bucket以及如何管理thet。
从这篇博客文章来看,unrdered_map是向量中的向量。
我的问题是:
- 假设bucket是"内部"向量是否正确
- 由于每个bucket(向量)可以包含多个元素,由哈希表上的哈希冲突("外部"向量)给出,并且由于我们必须扫描这个内部向量(在线性时间内),因此假设我们必须在密钥类型上定义equal方法(依赖于哈希运算符)才能找到bucket中的密钥,这正确吗
- 默认情况下,外部向量(哈希表)的大小是多少
- 默认情况下,内部向量大小是多少
- 如果一个bucket中的元素数量过大,会发生什么?换言之,当重洗发生时
很抱歉出现这些问题,但我没有找到任何详细的解释来解释这个结构是如何工作的(例如在cppreference.com上)。
std::unordereded_map是标准的C++哈希表。它曾经在STL中被称为hash_map,但在1998年STL的许多接口被合并到C++中时,它错过了机会。到2011年,许多库都有了自己的hash_map。C++不得不选择另一个名称(我认为"无序"是一个很好的选择;假设哈希表中的顺序是错误的常见来源)。
假设bucket是"内部"向量是否正确?
不,它既不正确(与迭代器无效要求不兼容),也很危险(在这种假设下,您最终可能会减去指向同一bucket中元素的指针)。
在现实生活中,bucket是链表;例如
- LLVM libc++
unordered_map
是__hash_node的链表数组的unique_ptr - GNU libstdc++
unordered_map
是指向_Hash_node链表数组的指针
假设我们必须在密钥类型上定义equal方法(依赖于hash运算符)才能在bucket中找到密钥,这正确吗?
是的,在bucket中定位密钥正是std::unordered_map
的第四个模板参数的作用(当然,不需要从字面上调用"密钥类型上的相等方法")
默认情况下,外部向量(哈希表)的大小是多少?
不存在"外部矢量"。默认构造的std::unordered_map
的bucket数量是由实现定义的,您可以使用bucket_count查询它。
默认情况下,内部向量大小是多少?
不存在"内部矢量"。任何给定bucket的大小等于当前放置在bucket中的元素数。您可以使用bucket_size 进行查询
如果一个bucket中的元素数量过大,会发生什么?换言之,当重洗发生时?
如果一个bucket中的元素数量过大,则不会发生任何事情。但是,如果每个bucket的平均元素数(也称为load_factor)超过max_load_factor,则会发生重新散列(例如插入时)
这可能有助于您理解bucket:http://www.cplusplus.com/reference/unordered_map/unordered_map/bucket_count/http://www.cplusplus.com/reference/unordered_map/unordered_map/max_load_factor/
但一般来说,是的,桶有点像内部向量。它需要一个相等运算符(或谓词)来区分具有与您建议的相同哈希的键。
存储桶的初始数量可能为0。它可以通过rehash()或reserve()进行设置(它们的语义略有不同。)
http://www.cplusplus.com/reference/unordered_map/unordered_map/rehash/
在理想情况下,每个bucket只有一个项目。您可以使用bucket_size进行检查。当负载系数(总项目数与存储桶数)变高时,它会自动重新灰。
默认情况下,它将以1:1的荷载系数为目标。如果散列函数是好的,这可能会持续到插入max_bucket_count项为止。
请记住,具体实施方式可能会有所不同。每个实现(例如,来自不同平台或标准库)实际上只需要具有正确的语义。
如果这些答案对你的程序很重要,你可以像我描述的那样查询这些值。如果你只是想了解它,在一些测试场景中查询它们,它可能会变得更清楚。
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 当 int 方法工作正常时,void 方法有何不同,或者为什么我不能调用 void 方法?
- sdl软件渲染器不工作,工作在硬件加速的一个