【问题标题】:Unordered map iterating by values按值迭代的无序映射
【发布时间】:2019-04-25 08:23:43
【问题描述】:

我有一个奇怪的问题,我不知道是我错过了阅读文档还是我的计算机正在做一些奇怪的事情。

我有一个 unordered_map。我想按桶顺序迭代 unordered_map 的桶。这部分很重要,因为我需要相对随机的访问。我搜索了 cplusplus.com 并找到了this。代码如下:

// unordered_map::bucket
#include <iostream>
#include <string>
#include <unordered_map>
int main ()
{
  std::unordered_map<std::string,std::string> mymap = {
    {"us","United States"},
    {"uk","United Kingdom"},
    {"fr","France"},
    {"de","Germany"}
  };

  for (auto& x: mymap) {
    std::cout << "Element [" << x.first << ":" << x.second << "]";
    std::cout << " is in bucket #" << mymap.bucket (x.first) << std::endl;
  }

  return 0;
}

我期待和想要在我的计算机上的输出是

Element [us:United States] is in bucket #1
Element [de:Germany] is in bucket #2
Element [fr:France] is in bucket #2
Element [uk:United Kingdom] is in bucket #4

但是我得到的输出是按奇怪的值类型排序的

Element [de:Germany] is in bucket #2
Element [fr:France] is in bucket #3
Element [uk:United Kingdom] is in bucket #1
Element [us:United States] is in bucket #1

我什至尝试用没有比较运算符的类替换该值,它仍然能够对它们进行排序。这与我的计算机存储地图的方式有关还是 cplusplus.com 已过时?我能够通过这样的循环遍历存储桶:

for ( unsigned int i = 0; i < b.bucket_count(); ++i) {

    for ( hash_table::const_local_iterator image_iterator = 
    b.begin(i);image_iterator!= b.end(i); ++image_iterator ){

唯一的问题是我需要能够跳过一定数量的值,即每 100 个值我只想要 1 个项目,这需要复杂的循环并且速度很慢。

任何帮助将不胜感激。我似乎无法弄清楚这一点!

[编辑] 在我的代码中,我的 unordered_map 实际上是 unordered_map,其中 point 是一个简单的类,它只有两个成员变量,没有辅助函数。

当我在地图上运行上面的循环时,这是我的输出。我已经链接了一个文本文件,因为它是一个很长的文件here 更让我困惑的是,我的 Point 类没有比较运算符。会不会是我的广告订单造成的?

【问题讨论】:

  • 请注意,您的输出也按键类型排序,也按存储桶顺序排序,但从 #2 开始,采用模运算。
  • 据我所知,迭代 std::unordered_map 时元素的顺序是未指定的。我理解为什么您可能希望它按桶订购它们,但我不知道有什么可以保证它的。显然这不是这里发生的事情。
  • 不清楚您指的是什么文档。未指定迭代 unordered_map 的顺序,因此不应在任何文档中给出。
  • 只是巧合。我可以使用您显示的特定键进行复制,但将它们更改为"a""b""c"、“d”和the output is no longer sorted(通过键或桶)。无序地图是无序的。
  • @MichaelHonaker 底线是您不能依赖unordered_map 的元素排序。顺序是未指定的,但这并不意味着随机。所以即使是一个奇怪的有序序列也可以是一个合法的排序。

标签: c++ c++11 unordered-map


【解决方案1】:

std::unordered_map中,特定元素的桶完全由在键上计算的哈希值决定,std::unordered_map用作std::hash的相应特化作为默认哈希函数,这是实现定义的,甚至不是保证在不同的程序执行过程中是相同的。见std::hash

正如@François Andrieux 在评论部分所说,std::unordered_map 的迭代顺序未指定,因此,您不能期望所有机器都具有相同的迭代行为,例如我的计算机中的输出是:

Element [de:Germany] is in bucket #0
Element [fr:France] is in bucket #3
Element [uk:United Kingdom] is in bucket #4
Element [us:United States] is in bucket #4

【讨论】:

  • 看看我的编辑。我的困惑是为什么它以这种方式排序,即使没有比较运算符
  • 没错,..但你不能指望在你尝试之前猜到它是什么 ...我的意思是,已修复...谢谢
猜你喜欢
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 1970-01-01
相关资源
最近更新 更多