c++ - 有序和无序映射

标签 c++ c++11

我正在尝试理解有序和无序 map

据我所知,有序 map 会对您的列表进行排序,而无序 map 不会对其进行排序。以此为基础site

但是为什么这段代码还是被排序了

std::unordered_map<std::string, int> map;

map.insert(std::make_pair("hello", 1));
map.insert(std::make_pair("world", 2));
map.insert(std::make_pair("call", 3));
map.insert(std::make_pair("ZZ", 4));

for(auto it = map.begin(); it != map.end();it++)
{
    std::cout << it->first << std::endl;
}

结果:

world
hello
call
ZZ

我不明白。应该先说 hello,然后是 world,然后再打电话,然后是 ZZ。如果世界的无序容器不应该对它进行排序,那么世界是如何首先出现的呢?

最佳答案

std::hash<std::string>为您的输入键生成哈希值。然后,对这些哈希值进行转换,以获得映射中存储桶的有效索引(人们能想到的最基本的索引是简单的模数)。这些操作需要恒定的时间并为您提供元素的位置。为了从转换后的哈希中获取好的项目,您需要将其放置在正确的位置。这就是为什么您会观察到输入的明显随机顺序。

现在您可以对计算索引的顺序做出没有假设。假设您要在 map 中添加更多字符串。也许某些字符串需要重新哈希,并且您的输入字符串可能会以另一种顺序出现。

这与插入顺序无关,没有理由保留,数据结构的目的是将项目放置在适当的位置,以便可以在摊销常数时间内检索它们(此处为将它们放置在转换后的哈希值给出的索引处)。

关于c++ - 有序和无序映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38430903/

相关文章:

c++ - 为什么 ranges::ostream_iterator 是默认可构造的?

c++ - 将 argv 复制到 char 数组时出错

c++ - 是否可以将对象向下转换为未在 C++ 中定义额外变量或 vtable 的子类?

c++ - 如何在 C++ 中返回 foreach 循环的值?

c++ - 而在std::cout , what does it work for?之前使用左移运算符(<<)

c++ - 比较 map 对象及其引用 C++

c++ - 具有模板参数的模板特化

c++ - 从部分专用模板类创建对象

c++ - 如何在 Qt Creator 上使用 pthread

c++ - 在 C++11 之后的现代 C++ 中使用原始指针