数据结构进阶 unordered_set unordered_map的使用

news/2024/11/9 3:01:34/

作者:@小萌新
专栏:@数据结构进阶
作者简介:大二学生 希望能和大家一起进步!
本篇博客简介:介绍高阶数据结构 unorder_set unorder_map的使用

unorder_set unorder_map

  • unordered系列关联式容器
  • unordered_set介绍
  • unordered_set的使用
    • unordered_set的定义方式
      • 方式一 构造一个某类型空容器
      • 方式二 拷贝构造某同类型容器的复制品
      • 方式三 使用迭代器拷贝构造一段内容
    • unordered_set的接口函数
      • 展示去重和范围for遍历
      • 展示直接去重
      • 展示迭代器遍历
      • 展示查找计数交换等
      • 展示交换容器
      • unordered_multiset
  • unordered_map的介绍
  • unordered_map的使用
    • unordered_map的定义方式
      • 方式一 构造一个某类型的空容器
      • 方式二 拷贝构造某类型容器的复制品
      • 方式三 使用迭代器拷贝构造某一段内容
    • unordered的接口函数
      • 展示去重和范围for遍历
      • 展示直接去重
      • 展示迭代器遍历
      • 展示查找
      • 展示【】运算符
      • 展示计数清除等
      • unordered_multimap

unordered系列关联式容器

在C++98中 STL提供了底层为红黑树的一系列关联式容器 在查询时效率可以达到Log(N)

即在最差的情况下 查询红黑树的高度次 这个时候的效率也不太理想

最好的查询是 通过很少的比较次数就能够将被查询元素找到

因此 在C++11中 STL又提供了四个unordered系列的关联式容器

这四个容器与map和set的用法相似 但底层结构不同

unordered_set介绍

  1. unordered_set是不按照特定顺序存储键值的关联式容器 其允许通过键值快速索引到对应元素
  2. 在unordered_set中 元素的值也是唯一标识它的key
  3. 在内部 unordered_set中的元素没有按照任何特定顺序排列 为了能在常数时间内找到key unordered_set将相同哈希值的键值放在桶中
  4. unordered_set查找单个元素的效率比set快 但是它遍历元素子集的范围迭代效率差
  5. 它的迭代器至少是前向迭代器

unordered_set的使用

unordered_set的定义方式

方式一 构造一个某类型空容器

	unordered_set<int> us1; // 构造一个int类型的空容器

方式二 拷贝构造某同类型容器的复制品

	unordered_set<int> us2(us1); // 构造某类型容器的复制品

方式三 使用迭代器拷贝构造一段内容

	string s1("hello world");unordered_set<char> us3(s1.begin(), s1.end()); // 使用string的迭代器拷贝构造

unordered_set的接口函数

在这里插入图片描述
迭代器相关函数如下
在这里插入图片描述

使用示例如下

展示去重和范围for遍历

	unordered_set<int> us1; // 构造一个int类型的空容器us1.insert(3);us1.insert(3);us1.insert(5);us1.insert(1);us1.insert(7);us1.insert(8);for (auto x: us1){cout << x << endl;}

我们使用unordered_set容器 并且插入多组重复数据 之后使用范围for遍历 达到一个去重的效果

注意 这里和set的区别是不会排序

展示直接去重

	unordered_set<int> us1; // 构造一个int类型的空容器us1.insert(3);us1.insert(3);us1.insert(5);us1.insert(1);us1.insert(7);us1.insert(8);for (auto x : us1){cout << x << " ";}cout << endl;us1.erase(3);for (auto x : us1){cout << x << " ";}cout << endl;

我们调用erase删除我们想要删除的值 并且再遍历一遍容器

在这里插入图片描述
我们可以发现 3被删除了

那么假如我们连续两次删除3会发生什么呢?

在这里插入图片描述

展示迭代器遍历

代码如下

	unordered_set<int> us1; // 构造一个int类型的空容器us1.insert(3);us1.insert(3);us1.insert(5);us1.insert(1);us1.insert(7);us1.insert(8);unordered_set<int>::iterator it = us1.begin();while (it != us1.end()){cout << *it << " ";it++;}cout << endl;

展示效果如下

在这里插入图片描述

展示查找计数交换等

	unordered_set<int> s1; // 构造一个int类型的空容器s1.insert(1);s1.insert(3);s1.insert(5);s1.insert(3);s1.insert(4);s1.insert(9);s1.insert(7);s1.insert(4);cout << s1.count(3) << endl;cout << s1.count(2) << endl;cout << s1.size() << endl;s1.clear();cout << s1.size() << endl;cout << s1.empty() << endl;

我们可以发现查找 3 2 出现的次数

s1的大小 清空后的大小 以及s1是否为空

在这里插入图片描述

展示交换容器

	unordered_set<int> s1; // 构造一个int类型的空容器s1.insert(1);s1.insert(3);s1.insert(5);s1.insert(3);s1.insert(4);s1.insert(9);s1.insert(7);s1.insert(4);unordered_set<int> s2;cout << s2.size() << endl;cout << s1.size() << endl;s2.swap(s1);cout << s2.size() << endl;cout << s1.size() << endl;

我们可以发现 交换后两个容器的大小发生了变化

unordered_multiset

unordered_multiset和unordered_set的底层实现都是相同的 接口函数也十分类似

它们之间最大的区别就是 unordered_multiset中允许键值对冗余

	unordered_multiset<int> us1; // 构造一个int类型的空容器us1.insert(3);us1.insert(3);us1.insert(5);us1.insert(1);us1.insert(7);us1.insert(8);for (auto x : us1){cout << x << " ";}cout << endl;

我们可以看到运行结果有冗余的键值

在这里插入图片描述
由于multiset容器允许键值冗余,因此两个容器中成员函数find和count的意义也有所不同

成员函数find功能
unordered_set容器返回键值为val的元素的迭代器
unordered_multiset容器返回底层哈希表中第一个找到的键值为val的元素的迭代器
成员函数count功能
unordered_set容器键值为val的元素存在则返回1,不存在则返回0(find成员函数可替代)
unordered_multiset容器返回键值为val的元素个数(find成员函数不可替代)

unordered_map的介绍

  1. unordered_map是储存<key,vlaue>键值对的关联式容器 其允许通过key值快速的索引到对应value值
  2. 在unordered_map中 键值通常用于唯一的标识元素 而映射值是一个对象 映射内容与此键关联 它们的类型可能不同
  3. 在内部 unordered_map没有对<key , value>按照任何顺序排序 为了能在常数范围内找到key值对应的value unordered_map将相同的哈希值的键值放在相同的桶中
  4. unordered_map通过key值访问单个元素比map快 但是在遍历元素子集的迭代方面效率差
  5. unordered_map实现了直接访问操作符【】 它允许使用key作为参数直接访问value
  6. 它的迭代器至少是前向迭代器

unordered_map的使用

unordered_map的定义方式

方式一 构造一个某类型的空容器

	unordered_map<int, int> um1; // 构造一个某类型的空容器

方式二 拷贝构造某类型容器的复制品

	unordered_map<int, int> um2(um1); // 拷贝构造某类型容器的复制品

方式三 使用迭代器拷贝构造某一段内容

	unordered_map<int, int> um3(um1.begin(), um1.end());// 使用迭代器拷贝构造某一段内容

unordered的接口函数

在这里插入图片描述
除了上述接口函数外 unordered_map还提供了一个功能十分强大的接口函数【】

  • 若当前容器中已有键值为key的键值对 则返回该键值对于value的引用
  • 若当前容器中无键值为key的键值对 则先插入键值对<key,value()> 之后返回该键值对于value的引用

迭代器相关函数如下

在这里插入图片描述
使用示例如下

展示去重和范围for遍历

	unordered_map<int, int> um1; // 构造一个某类型的空容器um1.insert(make_pair(3, 3));um1.insert(make_pair(3, 3));um1.insert(make_pair(5, 5));um1.insert(make_pair(1, 1));um1.insert(make_pair(7, 7));um1.insert(make_pair(8, 8));for (auto x : um1){cout << x.first << " ";}cout << endl;

我们使用unordered_map容器 并且插入多组重复数据之后使用范围for遍历 达到一个去重的效果

注意 这里和map的区别是不会排序

在这里插入图片描述

展示直接去重

	unordered_map<int, int> um1; // 构造一个某类型的空容器um1.insert(make_pair(3, 3));um1.insert(make_pair(3, 3));um1.insert(make_pair(5, 5));um1.insert(make_pair(1, 1));um1.insert(make_pair(7, 7));um1.insert(make_pair(8, 8));for (auto x : um1){cout << x.first << " ";}cout << endl;um1.erase(3);for (auto x : um1){cout << x.first << " ";}cout << endl;

我们调用erase删除我们想要删除的key值 并且再遍历一遍容器

在这里插入图片描述
我们可以发现3被删除了

那么假如我们连续两次删除3会发生什么呢?

在这里插入图片描述

展示迭代器遍历

代码如下

	unordered_map<int, int> um1; // 构造一个某类型的空容器um1.insert(make_pair(3, 3));um1.insert(make_pair(3, 3));um1.insert(make_pair(5, 5));um1.insert(make_pair(1, 1));um1.insert(make_pair(7, 7));um1.insert(make_pair(8, 8));auto it = um1.begin();while (it != um1.end()){cout << it->first << " ";it++;}cout << endl;

展示效果如下

在这里插入图片描述

展示查找

unordered_map的查找是根据key值在unordered_map中查找 有两种结果

  • 如果找到了则返回对应的迭代器
  • 如果找不到则返回end迭代器

代码和演示效果如下

	unordered_map<int, int> um1; // 构造一个某类型的空容器um1.insert(make_pair(3, 3));um1.insert(make_pair(3, 3));um1.insert(make_pair(5, 5));um1.insert(make_pair(1, 1));um1.insert(make_pair(7, 7));um1.insert(make_pair(8, 8));auto it = um1.find(3);auto it2 = um1.find(4);if (it != um1.end()){cout << it->first << endl;}if (it2 != um1.end()){cout << it2->first << endl;}

在这里插入图片描述

我们可以发现 确实符合上面的规则

展示【】运算符

首先我们明确下它的规则

  • 如果key不在unordered_map中 则使用【】会插入键值对 然后返回该键值对中value的引用
  • 如果key在unordered_map中则会返回键值为K的元素的value的引用

测试代码和结果如下

	unordered_map<int, int> um1; // 构造一个某类型的空容器um1.insert(make_pair(3, 3));um1.insert(make_pair(3, 3));um1.insert(make_pair(5, 5));um1.insert(make_pair(1, 1));um1.insert(make_pair(7, 7));um1.insert(make_pair(8, 8));um1[3] = 20;um1[9] = 9;auto it = um1.find(3);cout << it->second << endl;for (auto x : um1){cout << x.first << " ";}

在这里插入图片描述
我们可以看到 进行了

	um1[3] = 20;um1[9] = 9;

这两步操作之后

key值为3的value变成了20

多了一个key值为9的元素

展示计数清除等

这里很简单 直接看代码和演示结果就可以

	unordered_map<int, int> um1; // 构造一个某类型的空容器um1.insert(make_pair(3, 3));um1.insert(make_pair(3, 3));um1.insert(make_pair(5, 5));um1.insert(make_pair(1, 1));um1.insert(make_pair(7, 7));cout << um1.size() << endl;um1.clear();cout << um1.size() << endl;

在这里插入图片描述

unordered_multimap

unordered_multimap和unordered_map的底层实现都是相同的 接口函数也十分类似

它们之间最大的区别就是 unordered_multimap中允许键值对冗余

代码和演示结果如下

	unordered_multimap<int, int> um1; // 构造一个某类型的空容器um1.insert(make_pair(3, 3));um1.insert(make_pair(3, 3));um1.insert(make_pair(5, 5));um1.insert(make_pair(1, 1));um1.insert(make_pair(7, 7));for (auto x : um1){cout << x.first << " ";}

在这里插入图片描述
由于unordered_multimap容器允许键值对的键值冗余 因此该容器中成员函数find和count的意义与unordered_map容器中的也有所不同

成员函数find功能
unordered_map容器返回键值为key的键值对的迭代器
unordered_multimap容器返回底层哈希表中第一个找到的键值为key的键值对的迭代器
成员函数count功能
unordered_map容器键值为key的键值对存在则返回1,不存在则返回0(find成员函数可替代)
unordered_multimap容器返回键值为key的键值对的个数(find成员函数不可替代)

此外由于unordered_multimap容器允许键值对冗余 因此【】操作符可能会产生歧义 因此在unordered_multimap容器中并未实现之


http://www.ppmy.cn/news/18436.html

相关文章

89. 注意力机制以及代码实现Nadaraya-Waston 核回归

1. 心理学 动物需要在复杂环境下有效关注值得注意的点心理学框架&#xff1a;人类根据随意线索和不随意线索选择注意点 随意&#xff1a;随着自己的意识&#xff0c;有点强调主观能动性的意味。 2. 注意力机制 2. 非参注意力池化层 3. Nadaraya-Waston 核回归 4. 参数化的注意…

OpenCV级联分类器

OpenCV级联分类器 概览 OpenCV: 一个计算机视觉库, 提供了一种称级联分类器的方法检测对象级联分类器:一种基于AdaBoost算法的多级分类器, 用于在图像中检测目标对象. 它通过不断学习组合多个特征来识别目标对象. 每一级中, 级联分类器先检测出可能是目标对象的部分, 然后再这…

联合证券|港股再融资“春江水暖” 资本争购热门赛道企业

进入2023年&#xff0c;港股再融资商场有所回暖。到1月18日&#xff0c;已有27家港股上市公司发布拟配售股份&#xff08;简称“配股”&#xff09;再融资&#xff0c;募资总额164.01亿港元&#xff0c;较上一年同期增加148.16%。其间&#xff0c;微盟集团的配股再融资吸引了众…

python+selenium爬虫自动化批量下载文件

一、项目需求 在一个业务网站有可以一个个打开有相关内容的文本&#xff0c;需要逐个保存为TXT&#xff0c;数据量是以千为单位&#xff0c;人工操作会麻木到崩溃。 二、解决方案 目前的基础办法就是使用pythonselenium自动化来代替人工去操作&#xff0c;虽然效率比其他爬虫…

Java基础练习题(四)

13.求两点之间的距离 题目描述 给定A(x1, y1), B(x2, y2)两点坐标,计算它们间的距离。 输入 输入包含四个实数x1, y1, x2, y2,分别用空格隔开,含义如描述。其中0≤x1,x2,y1,y2≤100。 输出 输出占一行,包含一个实数d,表示A, B两点间的距离。结果保留两位小数。 样例输入

经典同步问题

同步问题是一个复杂的问题&#xff0c;但是它也有自己的方法去处理、去分析。PV操作系统的解题思路&#xff1a;关系分析。找出题目中描述的各个进程&#xff0c;分析它们之间的同步、互斥关系。(从事件的角度分析)整理思路。根据各进程的操作流程确定P、V操作的大致顺序。设置…

Cert Manager 申请SSL证书流程及相关概念-二

中英文对照表 英文英文 - K8S CRD中文备注certificatesCertificate证书certificates.cert-manager.io/v1certificate issuersIssuer证书颁发者issuers.cert-manager.ioClusterIssuer集群证书颁发者clusterissuers.cert-manager.iocertificate requestCertificateRequest证书申…

python—-下载Iwara视频

1.提示&#xff1a; 使用需要安装bs4库&#xff0c;selenium库&#xff0c;fake_useragent库&#xff0c;版本没什么要求 同时需要安装相同版本的Chrome浏览器和驱动器&#xff0c;注意驱动器和浏览器不一样哦 哦对了&#xff0c;还要自备梯子&#xff08;不过某喵天天在Iwara打…