根据按键类型选择地图或unordered_map
Selection of map or unordered_map based on keys's type
一个普遍询问的问题是,我们是否应该使用unordered_map或地图以更快地访问。这个问题的最常见(相当古老)的答案是:如果您想直接访问单个元素,请使用unordered_map,但是如果要迭代元素(最有可能以分类方式)使用地图。
在做出这样的选择时,我们不应该考虑键的数据类型吗?作为一种数据类型(例如int)的哈希算法可能比其他(例如字符串)更容易碰撞。
如果是这种情况(哈希算法很容易碰撞),那么我可能会使用映射即可直接访问,例如o(1)o(1)恒定时间(可能在输入的大型输入中平均)unordered_map映射即使对于n。
您提出了一个很好的观点...但是您专注于错误的部分。
问题本身不是键的类型,而是用于推导该键的哈希值的哈希函数。
词典订购是 easy :如果您告诉我您想根据其3个字段订购结构(他们已经支持订购自己),那么我只写信:
bool operator<(Struct const& left, Struct const& right) {
return boost::tie(left._1, left._2, left._3)
< boost::tie(right._1, right._2, right._3);
}
我完成了!
但是编写哈希函数是困难。您需要一些有关数据分布(统计)的知识,您可能需要防止专门制作的攻击等...老实说,我希望很多人都能能够制作出良好的哈希功能。但是最糟糕的部分是,构图也很难!给定两个独立字段,将其哈希值右组合很难(提示: boost::hash_combine
)。
因此,确实,如果您不知道自己在做什么,并且正在处理用户制作的数据,那就坚持使用map
。也许较慢(不确定),但是更安全。
实际上并没有像碰撞易于对象那样的东西,因为此东西取决于您使用的哈希函数。假设对象不完全相同 - 可以使用一些功能来创建一个有益的哈希函数。
假设您对数据有一些知识 - 并且您知道某些哈希函数h1()
可能会有很多碰撞 - 那么您应该找到并使用不同的哈希函数h2()
,这更适合此任务。/p>
也就是说,还有其他问题以及为什么基于树的数据结构而不是哈希基础(例如延迟和集合的大小),我的答案在此线程中涵盖了一些。
毫无意义地试图对此太聪明。与往常一样,配置文件,比较,优化如果有用。涉及许多因素 - 标准中未指定的很多因素,并且会因编译器而异。有些事情可能会在特定的硬件上更好或更糟。如果您对这些东西感兴趣(或付费假装为),则应该更加系统地了解这些东西。您可能首先要学习一些有关实际哈希功能及其特征的知识。找不到所有实际目的的哈希函数非常罕见,没有比随机但可重复的值更碰撞的倾斜度 - 有时候,接近这一点的次数比处理一些额外的碰撞要慢。
- 为什么不;名字在地图上是按顺序排列的吗
- 基于多个条件处理地图中的所有元素
- 在C++中将矢量转换为嵌套地图
- 替换基于地图的所有引用
- 如何区分地图中的 0 和 false?
- 地图计数确实很重要,或者只是检查是否存在
- 如何从地图中删除矢量对象
- 是否有任何C++功能可以对地图进行排序?
- 如何使用 std::variant 打印地图键/值?
- 从矢量或地图中删除共享指针
- 在 c++ 中,有一种方法可以创建一个包含地图作为值的树状地图?
- 无限嵌套具有变体的地图
- C++一会儿循环读到地图上 2 行?
- 如何在cpp中使用地图显示给定日期范围内(在下面的问题中)的费率?
- 如何检查变量是否是C++中的地图?
- 如何使地图按值C++排序
- 修改地图内矢量中的值
- 为什么我在地图中搜索STL时差很大?
- 我正在尝试按降序对地图进行排序,但没有得到预期的结果?
- 如何包装(撰写)增强 hana 地图并访问括号运算符(运算符 [])?