1、介绍

unordered_map,它是一个关联容器,内部采用的是hash表结构,拥有快速检索的功能。

1.1、特性

  1. 关联性:通过key去检索value,而不是通过绝对地址(和顺序容器不同)
  2. 无序性:使用hash表存储,内部无序
  3. Map : 每个值对应一个键值
  4. 键唯一性:不存在两个元素的键一样
  5. 动态内存管理:使用内存管理模型来动态管理所需要的内存空间

由于unordered_map内部采用的hashtable的数据结构存储,所以,每个特定的key会通过一些特定的哈希运算映射到一个特定的位置,我们知道,hashtable是可能存在冲突的(多个key通过计算映射到同一个位置),在同一个位置的元素会按顺序链在后面。所以把这个位置称为一个bucket是十分形象的(像桶子一样,可以装多个元素)。

unordered_map内部其实是由很多哈希桶组成的,每个哈希桶中可能没有元素,也可能有多个元素。

1.2、模板

1 template < class Key,                                    // 键值对中键的类型
2 class T, // 键值对中值的类型
3 class Hash = hash<Key>, // 容器内部存储键值对所用的哈希函数
4 class Pred = equal_to<Key>, // 判断各个键值对键相同的规则
5 class Alloc = allocator< pair<const Key,T> > // 指定分配器对象的类型
6 > class unordered_map;

主要使用的也是模板的前2个参数<键,值>

unordered_map<const Key, T> map;
参数 含义
<key,T> 前 2 个参数分别用于确定键值对中键和值的类型,也就是存储键值对的类型。
Hash = hash<Key> 用于指明容器在存储各个键值对时要使用的哈希函数,默认使用 STL 标准库提供的 hash<key> 哈希函数。注意,默认哈希函数只适用于基本数据类型(包括 string 类型),而不适用于自定义的结构体或者类。
Pred = equal_to<Key> 要知道,unordered_map 容器中存储的各个键值对的键是不能相等的,而判断是否相等的规则,就由此参数指定。默认情况下,使用 STL 标准库中提供的 equal_to<key> 规则,该规则仅支持可直接用 == 运算符做比较的数据类型。

1.3、unordered_map的构造函数

(1)默认构造函数:

unordered_map<int, string> mymap;

(2)使用n个元素构造unordered_map:

unordered_map<int, string> mymap = {{1, "one"}, {2, "two"}, {3, "three"}};

(3)使用给定的范围构造unordered_map:

1 vector<pair<int, string>> myVector = {{1, "one"}, {2, "two"}, {3, "three"}};
2 unordered_map<int, string> mymap(myVector.begin(), myVector.end());

(4)使用给定的哈希函数和相等比较函数构造unordered_map:

 1 struct myHashFunction {
2 size_t operator()(const int& key) const {
3 return hash<int>()(key);
4 }
5 };
6
7 struct myEqualFunction {
8 bool operator()(const int& key1, const int& key2) const {
9 return key1 == key2;
10 }
11 };
12
13 unordered_map<int, string, myHashFunction, myEqualFunction> mymap;

2、unordered_map的函数应用

成员方法 功能
begin() 返回指向容器中第一个键值对的正向迭代器。
end()  返回指向容器中最后一个键值对之后位置的正向迭代器。
cbegin() 和 begin() 功能相同,只不过在其基础上增加了 const 属性,即该方法返回的迭代器不能用于修改容器内存储的键值对。
cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,即该方法返回的迭代器不能用于修改容器内存储的键值对。
empty() 若容器为空,则返回 true;否则 false。
size() 返回当前容器中存有键值对的个数。

2.1、unordered_map迭代器的示例:

(1)使用迭代器遍历unordered_map,从begin()到end()。在循环中,使用it->first和it->second分别访问键和值。

 1 #include <iostream>
2 #include <unordered_map>
3 int main() {
4 std::unordered_map<int, std::string> mymap = {{1, "one"}, {2, "two"}, {3, "three"}};
5 // 使用迭代器遍历unordered_map
6 for (auto it = mymap.begin(); it != mymap.end(); ++it) {
7 std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;
8 }
9 return 0;
10 }
11 //Key: 1, Value: one
12 //Key: 2, Value: two
13 //Key: 3, Value: three

(2)使用范围for循环遍历unordered_map,这种方式更加简洁。使用const auto& pair来捕获每个键值对,并使用pair.first和pair.second分别访问键和值。

 1 #include <iostream>
2 #include <unordered_map>
3 int main() {
4 std::unordered_map<int, std::string> mymap = {{1, "one"}, {2, "two"}, {3, "three"}};
5 // 使用范围for循环遍历unordered_map
6 for (const auto& pair : mymap) {
7 std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
8 }
9 return 0;
10 }
11 //Key: 1, Value: one
12 //Key: 2, Value: two
13 //Key: 3, Value: three

2.2、unordered_map的容量和访问函数

max_size() 返回容器所能容纳键值对的最大个数,不同的操作系统,其返回值亦不相同。
operator[key] 该模板类中重载了 [] 运算符,其功能是可以向访问数组中元素那样,只要给定某个键值对的键 key,就可以获取该键对应的值。注意,如果当前容器中没有以 key 为键的键值对,则其会使用该键向当前容器中插入一个新键值对。
at(key) 返回容器中存储的键 key 对应的值,如果 key 不存在,则会抛出 out_of_range 异常。 
find(key) 查找以 key 为键的键值对,如果找到,则返回一个指向该键值对的正向迭代器;反之,则返回一个指向容器中最后一个键值对之后位置的迭代器(如果 end() 方法返回的迭代器)。
count(key) 在容器中查找以 key 键的键值对的个数。

(1)empty() 函数用于检查 unordered_map 是否为空,即是否不包含任何键值对。如果 unordered_map 为空,则返回 true;否则返回 false。

 1 #include <iostream>
2 #include <unordered_map>
3 int main() {
4 std::unordered_map<int, std::string> myMap;
5
6 if (myMap.empty()) {
7 std::cout << "myMap is empty" << std::endl;
8 } else {
9 std::cout << "myMap is not empty" << std::endl;
10 }
11
12 myMap = {{1, "one"}, {2, "two"}, {3, "three"}};
13
14 if (myMap.empty()) {
15 std::cout << "myMap is empty" << std::endl;
16 } else {
17 std::cout << "myMap is not empty" << std::endl;
18 }
19
20 return 0;
21 }
22 //myMap is empty
23 //myMap is not empty

(2)size() 函数返回 unordered_map 中存储的键值对的数量。

 1 #include <iostream>
2 #include <unordered_map>
3
4 int main() {
5 std::unordered_map<int, std::string> myMap = {{1, "one"}, {2, "two"}, {3, "three"}};
6
7 std::cout << "Size of myMap: " << myMap.size() << std::endl;
8
9 return 0;
10 }
11 //Size of myMap: 3

(3)operator[] 用于访问或修改指定键的值。如果键不存在,则会插入一个新的键值对,其中键为指定的键,值为该类型的默认值。

 1 #include <iostream>
2 #include <unordered_map>
3
4 int main() {
5 std::unordered_map<std::string, int> my_map;
6
7 // 使用operator[]插入键值对
8 my_map["apple"] = 1;
9 my_map["banana"] = 2;
10
11 // 使用operator[]访问键值对
12 std::cout << "Apple: " << my_map["apple"] << std::endl;
13 std::cout << "Banana: " << my_map["banana"] << std::endl;
14
15 // 如果键不存在,operator[]将插入新的键值对,并赋予默认值
16 std::cout << "Orange: " << my_map["orange"] << std::endl;
17
18 return 0;
19 }
20 //Apple: 1
21 //Banana: 2
22 //Orange: 0

(4)find方法用于查找具有指定键的元素

 1 std::unordered_map<Key, Value> my_map;
2 // 插入一些元素...
3
4 // 使用find方法查找具有指定键的元素
5 auto it = my_map.find("key");
6
7 if (it != my_map.end()) {
8 // 键存在于unordered_map中
9 std::cout << "Found key: " << it->first << ", value: " << it->second << std::endl;
10 } else {
11 // 键不存在于unordered_map中
12 std::cout << "Key not found" << std::endl;
13 }

(5)count方法用于获取具有指定键的元素的数量

 1 std::unordered_map<Key, Value> my_map;
2 // 插入一些元素...
3
4 // 使用count方法获取具有指定键的元素数量
5 size_t count = my_map.count("key");
6
7 if (count > 0) {
8 std::cout << "Key found" << std::endl;
9 } else {
10 std::cout << "Key not found" << std::endl;
11 }

(6)insert方法用于插入元素

 1 std::unordered_map<Key, Value> my_map;
2
3 // 使用insert方法插入元素
4 std::pair<std::unordered_map<Key, Value>::iterator, bool> result = my_map.insert({"key", "value"});
5
6 if (result.second) {
7 // 插入成功
8 std::cout << "Inserted key: " << result.first->first << ", value: " << result.first->second << std::endl;
9 } else {
10 // 插入失败(键已存在)
11 std::cout << "Key already exists" << std::endl;
12 }
13
14 //Inserted key: key, value: value

(7)erase方法用于删除元素

 1 std::unordered_map<Key, Value> my_map;
2 // 插入一些元素...
3
4 // 使用erase方法删除具有指定键的元素
5 auto it = my_map.find("key");
6 if (it != my_map.end()) {
7 my_map.erase(it);
8 std::cout << "Erased key: " << it->first << std::endl;
9 } else {
10 std::cout << "Key not found" << std::endl;
11 }
12
13 //Erased key: key

(8)clear方法用于删除所有元素

 1 std::unordered_map<Key, Value> my_map;
2 // 插入一些元素...
3
4 // 使用clear方法删除所有元素
5 my_map.clear();
6
7 if (my_map.empty()) {
8 std::cout << "Map is empty" << std::endl;
9 } else {
10 std::cout << "Map is not empty" << std::endl;
11 }
12
13 //Map is empty

(9)swap方法用于交换两个unordered_map对象的内容

 1 std::unordered_map<Key, Value> my_map1;
2 // 插入一些元素到my_map1...
3
4 std::unordered_map<Key, Value> my_map2;
5 // 插入一些元素到my_map2...
6
7 // 使用swap方法交换my_map1和my_map2的内容
8 my_map1.swap(my_map2);
9
10 // 现在my_map1包含my_map2以前的元素,反之亦然

 (10)其他

 1 #include <iostream>
2 #include <string>
3 #include <unordered_map>
4 using namespace std;
5 int main()
6 {
7 //创建空 umap 容器
8 unordered_map<string, string> umap;
9 //向 umap 容器添加新键值对
10 umap.emplace("Python教程", "http://c.biancheng.net/python/");
11 umap.emplace("Java教程", "http://c.biancheng.net/java/");
12 umap.emplace("Linux教程", "http://c.biancheng.net/linux/");
13 //输出 umap 存储键值对的数量
14 cout << "umap size = " << umap.size() << endl;
15 //使用迭代器输出 umap 容器存储的所有键值对
16 for (auto iter = umap.begin(); iter != umap.end(); ++iter) {
17 cout << iter->first << " " << iter->second << endl;
18 }
19 return 0;
20 }

unordered_map的理解和应用的更多相关文章

  1. c++ 标准库的各种容器(vector,deque,map,set,unordered_map,unordered_set,list)的性能考虑

    转自:http://blog.csdn.net/truexf/article/details/17303263 一.vector vector采用一段连续的内存来存储其元素,向vector添加元素的时 ...

  2. map,hash_map和unordered_map 实现比较

    map介绍 Map是STL[1]的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处 ...

  3. stl vector、红黑树、set、multiset、map、multimap、迭代器失效、哈希表(hash_table)、hashset、hashmap、unordered_map、list

    stl:即标准模板库,该库包含了诸多在计算机科学领域里所常用的基本数据结构和基本算法 六大组件: 容器.迭代器.算法.仿函数.空间配置器.迭代适配器 迭代器:迭代器(iterator)是一种抽象的设计 ...

  4. PAT甲级——1095 Cars on Campus (排序、映射、字符串操作、题意理解)

    本文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/93135047 1095 Cars on Campus (30 分 ...

  5. hash表的理解

    哈希表 先从数组说起 任何一个程序员,基本上对数组都不会陌生,这个最常用的数据结构,说到它的优点,最明显的就是两点: 简单易用,数组的简易操作甚至让大多数程序员依赖上了它,在资源富足的情况下,我们甚至 ...

  6. c++ unordered_map 自定义key

    C++11新增了一类散列容器包括unordered_set, unordered_map, unordered_multiset, unordered_multimap, 即之前熟悉的hash_set ...

  7. C++进阶(unordered_set+unordered_map模拟实现)

    unordered_set unordered_set是以无特定顺序存储唯一元素的容器,并且允许根据它们的值快速检索单个元素,是一种K模型. 在unordered_set中,元素的值同时是它的key, ...

  8. C++入门之unordered_map

    1.介绍   unordered_map是c++语言STL库中一个比较重要的容器,不能自动排序,这一容器是根据哈希表这一数据结构设计而成的,能够极大地提升数据搜索.插入和删除操作的时间效率. 2.头文 ...

  9. 理解CSS视觉格式化

    前面的话   CSS视觉格式化这个词可能比较陌生,但说起盒模型可能就恍然大悟了.实际上,盒模型只是CSS视觉格式化的一部分.视觉格式化分为块级和行内两种处理方式.理解视觉格式化,可以确定得到的效果是应 ...

  10. 彻底理解AC多模式匹配算法

    (本文尤其适合遍览网上的讲解而仍百思不得姐的同学) 一.原理 AC自动机首先将模式组记录为Trie字典树的形式,以节点表示不同状态,边上标以字母表中的字符,表示状态的转移.根节点状态记为0状态,表示起 ...

随机推荐

  1. 揭秘C#异步编程核心机制:从状态机到线程池的全面拆解

    C#中的异步编程是一个强大且复杂的特性,它允许开发者编写非阻塞的代码,从而显著提升应用程序的响应性和吞吐量.本文将深入剖析异步编程的底层原理,从async和await关键字的工作机制,到状态机.任务调 ...

  2. 使用wxWidgets进行跨平台GUI开发(附1)

    补充说明wxWidgets在Windows下使用CMake的配置 wxWidgets官方提供了一个在Windows下使用CMake来构建wxWidgets库的方法,这样便于你自己用CMake构建项目. ...

  3. ArcGIS工具操作报错999999的通用处理方式

      本文介绍一种解决ArcGIS中ERROR 999999报错(Configuration RasterCommander ImageServer can not be started)的方法.    ...

  4. HyperMesh模型导入与几何清理

    2.1 CAD 模型导入与修复 HyperMesh 支持多种主流 CAD 格式模型文件,同时针对模型在软件之间导入导出过程中可能出现数据丢失的问题提供了多种修复工具. CAD 模型导入与修复可进行: ...

  5. 数栈 × AWS EMR On EC2 适配实践:打造出海企业可落地的云上数据中台解决方案

    随着袋鼠云全面推进数栈产品的出海战略,我们在服务多个头部出海客户的过程中发现,真正做好"海外可用"的数据平台,关键不仅在于部署全球化,还在于深入适配 AWS 的核心计算平台EMR, ...

  6. TypeScript 类型判断

    多谢大哥的指教. https://www.wenjiangs.com/doc/typescript-typeguard instanceof instanceof 与 typeof 类似,区别在于 t ...

  7. FastGithub 使用遇到问题

    火狐浏览器 https://blog.csdn.net/weixin_33847182/article/details/86129219 因 HTTP 严格传输安全(HSTS)机制无法打开网页 1.打 ...

  8. Jquery获取div的宽度与高度

    https://blog.csdn.net/qq2468103252/article/details/82835563 宽度$('div').width(); 区块的本身宽度$('div').oute ...

  9. Jquery 选择html 标签获取值

    https://zhidao.baidu.com/question/299628455.html 这个问题包含两个方面:jquery选择器(即针对你指定的那个input元素)和获取内容(即获得输入的值 ...

  10. leetcode 1406

    简介 国服第一的刷题视频 参考链接 https://www.bilibili.com/video/BV1W54y197NM?from=search&seid=16875469481128889 ...