C++之unordered_map/set的使用

前面我们已经学习了STL中底层为红黑树结构的一系列关联式容器——set/multiset 和 map/multimap(C++98).


unordered系列关联式容器

C++98中, STL提供了底层为红黑树结构的一系列关联式容器, 在查询时效率可达到log2N,即最差情况下需要比较红黑树的高度次, 当树中的节点非常多时, 查询效率也不理想.

最好的查询是, 进行很少的比较次数就能够将元素找到, 因此在C++11中, STL又提供了4个unordered系列的关联式容器, 这四个容器与红黑树结构的关联式容器使用方式基本类似, 只是其底层结构不同.


map,set系列容器和unordered_map,unordered_set系列容器的区别 

1.它们的底层结构是不一样的:

set/multiset 和 map/multimap它们的底层结构是红黑树, 而unordered系列的——unordered_map/unordered_multimap, unordered_set/unordered_multiset它们的底层是哈希表.

unordered系列中, 带multi的和不带multi的区别也是允许键值重复出现和不允许重复出现的问题.

2.从名字上我们其实就能得出它们的第二个区别:

unordered是无序的意思, 所以map和set我们用迭代器遍历, 得到的是有序的序列, unordered系列去遍历的话, 得到的是无序的, 单从使用上来说最大的区别就是有没有序的问题.

3.map和set系列它们的迭代器是双向迭代器, 而unordered系列它们的迭代器是单向迭代器.

4. unorder _ map 容器通过键访问单个元素的速度比 map 容器快, 尽管它们通过元素的子集进行范围迭代的效率通常较低.(和底层实现有关)


 unordered_map和unordered_set的使用

单从使用来说, 这和set/multiset 和 map/multimap的使用用法基本一致, 常用的接口都差不多.

unordered_map的接口:

unordered_map的构造:

函数声明功能介绍
unordered_map构造不同格式的unordered_map对象

 unordered_map的容量:

函数声明功能介绍
bool empty() const检测unordered_map是否为空
size_t size() const获取unordered_map的有效元素个数

unordered_map的迭代器:

函数声明功能介绍
begin返回unordered_map第一个元素的迭代器
end返回unordered_map最后一个元素下一个位置的迭代器
cbegin返回unordered_map第一个元素的const迭代器
cend返回unordered_map最后一个元素下一个位置的const迭代器

unordered_map的元素访问:

函数声明功能介绍
operator[]返回与key对应的value

注意: 该函数中实际调用哈希桶的插入操作, 用参数key与V()构造一个默认值往底层哈希桶
中插入, 如果key不在哈希桶中, 插入成功, 返回V(); 插入失败, 说明key已经在哈希桶中,
将key对应的value返回

unordered_map的查询:

函数声明功能介绍
iterator find(const K& key)返回key在哈希桶中的位置
size_t count(const K& key)返回哈希桶中关键码为key的键值对的个数

注意: unordered_map中key是不能重复的,因此count函数的返回值最大为1 

unordered_map的修改:

函数声明功能介绍
insert向容器中插入键值对
erase删除容器中的键值对
void clear()清空容器中有效元素个数
void swap(unordered_map&)交换两个容器中的元素

unordered_map的桶操作:

函数声明功能介绍
size_t bucket_count()const返回哈希桶中桶的总个数
size_t bucket_size(size_t n)const返回n号桶中有效元素的总个数
size_t bucket(const K& key)返回元素key所在的桶号

它的迭代器没有rbegin、rend, 因为它的迭代器是单向的,不支持反向遍历。


 unordered_set的接口:

 接口也都差不多,只是set系列的没有[]和at接口.

#include<set>
#include<unordered_set>
#include<iostream>
using namespace std;

int main()
{
	set<int> s1;
	unordered_set<int> s2;

	s1.insert(1);
	s1.insert(5);
	s1.insert(4);
	s1.insert(3);
	s1.insert(8);
	for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
		cout << *it << " ";
//
	cout << endl;
//
	s2.insert(1);
	s2.insert(5);
	s2.insert(4);
	s2.insert(3);
	s2.insert(8);
	for (unordered_set<int>::iterator it = s2.begin(); it != s2.end(); it++)
		cout << *it << " ";

	return 0;
}

 

可以看到set按迭代器访问是有序的, unordered_set按迭代器访问是按照插入顺序访问的, unordered_map也是一样.


set与unordered_set性能对比 

void test2()
{
	srand(time(nullptr));
	size_t N = 1000000;
	unordered_set<int> us;
	set<int> s;

	vector<int> v;
	v.reserve(N);
	for (size_t i = 0; i < N; i++)
	{
		v.push_back(rand()+i);//减少重复值
	}

	size_t begin1 = clock();
	for (auto& e : v)
		s.insert(e);
	size_t end1= clock();
	cout << "set insert:" << end1 - begin1 << endl;

	size_t begin2 = clock();
	for (auto& e : v)
		us.insert(e);
	size_t end2 = clock();
	cout << "unordered_set insert:" << end2 - begin2 << endl;

	size_t begin3 = clock();
	for (auto& e : v)
		s.find(e);
	size_t end3 = clock();
	cout << "set find:" << end3- begin3 << endl;

	size_t begin4 = clock();
	for (auto& e : v)
		us.find(e);
	size_t end4 = clock();
	cout << "unordered_set find:" << end4 - begin4 << endl;

	size_t begin5 = clock();
	for (auto& e : v)
		s.erase(e);
	size_t end5 = clock();
	cout << "set erase:" << end5 - begin5 << endl;

	size_t begin6 = clock();
	for (auto& e : v)
		us.erase(e);
	size_t end6 = clock();
	cout << "unordered_set erase:" << end6 - begin6 << endl;

}

所以, 综合而言, unordered系列的效率是比较高的, 尤其是find的效率.


OJ例题

349. 两个数组的交集 - 力扣(LeetCode) 

map和set的例题-CSDN博客

之前有用set的解法, 排序加去重可以解决, 现在可以用unordered_set, unordered_set虽然不能排序, 但是也是可以去重的, 首先我们先对两个数组进行去重, 然后, 我们遍历其中一个数组, 遍历的同时去依次判断当前元素在不在另一个数组中, 如果在就是交集。


 350. 两个数组的交集 II - 力扣(LeetCode)

返回结果中每个元素出现的次数, 应与元素在两个数组中都出现的次数一致(如果在两数组中出现次数不一致,则考虑取较小值), 但是它没有要去输出结果中每个元素是唯一的。 


 

统计次数, 判断有没有次数大于1的就行了:


 884. 两句话中的不常见单词 - 力扣(LeetCode)

这道题其实可以求转化成两个字符串合并后, 只出现一次的单词.

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/185331.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

牛气霸屏-快抖云推独立版V1.6.7

介绍 快抖云推全插件独立版是最近很火的牛气霸屏系统独立版&#xff0c;牛气霸屏系统就是商家通过系统在线创建抖音或快手霸屏活动&#xff0c;并生成该活动的爆客二维码&#xff0c;用户通过扫二维码即可参加活动&#xff08;活动可以是领取卡劵&#xff0c;抽奖等&#xff0…

PyQt6简介

锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计12条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话版…

如何用SWIG封装c++接口给java使用?

SWIG是什么&#xff1f; SWIG(Simplified Wrapper and Interface Generator)是一个将C/C接口转换为其他语言接口的工具&#xff0c;从而可以讲C/C的库集成到其他语言的系统中。目前SWIG已经可以支持Python, Java, C#,Ruby&#xff0c;PHP,R语言等十多种语言。 官方网址&…

Excel使用VLOOKUP查询数据

VLOOKUP函数在百度百科中的解释是&#xff1a; 解释一下&#xff0c;函数需要4个参数&#xff1a; 参数1&#xff08;lookup_value&#xff09;&#xff1a;需要匹配的值参数2&#xff08;table_array&#xff09;&#xff1a;在哪个区域里进行匹配参数3&#xff08;col_index…

Celonis推出流程智能图,希望建立首个世界级“流程智能维基百科”

近日&#xff0c;全球流程挖掘领域的领导者Celonis在其年度客户大会Celosphere上推出了流程智能领域的一项创新&#xff0c;即流程智能图Process Intelligence Graph™&#xff08;PI Graph&#xff09;。 PI Graph 是一个与具体系统无关的、丰富的业务数字孪生体&#xff0c;…

三菱PLC应用[集锦]

三菱PLC应用[集锦] 如何判断用PNP还是NPN的个人工作心得 10&#xff5e;30VDC接近开关与PLC连接时&#xff0c;如何判断用PNP还是NPN的个人工作心得: 对于PLC的开关量输入回路。我个人感觉日本三菱的要好得多&#xff0c;甚至比西门子等赫赫大名的PLC都要实用和可靠&#xff01…

9.输出国际象棋盘【2023.11.24】

1.问题描述 要求输出国际象棋棋盘。 2.解决思路 国际象棋棋盘由64个黑白相间的格子组成&#xff0c;分为8行*8列。用i控制行&#xff0c;j控制列&#xff0c;根据ij的和的变化来控制输出黑方格还是白方格。 3.代码实现 #include<stdio.h> int main(){for(int i0;i&…

亚马逊运营中动态/静态住宅IP代理的应用有哪些?

作为全球最大的电商平台之一&#xff0c;亚马逊已经成为许多商家的首选销售平台。而代理IP作为近几天互联网的热门工具&#xff0c;在跨境电商界也起着非常强大的作用。那么在亚马逊运营中&#xff0c;适合动态住宅代理还是静态住宅代理呢&#xff1f;下面我们一起来探索&#…

基于LiteFlow构建实时会员权益体系

知识简介&#xff1a;通过LiteFlow规则引擎构建会员权益体系&#xff0c;实现权益节点可插拔&#xff0c;可编排&#xff0c;可复用的特性。完成会员权益数据底盘建设&#xff0c;将分散的权益数据集中&#xff0c;提升权益查询及管理水平。 历史痛点 1&#xff09;不同等级权…

MySQL 基于成本的优化

其实在MySQL中⼀条查询语句的执⾏成本是由下边这两个⽅⾯组成的&#xff1a; I/O成本 我们的表经常使⽤的MyISAM、InnoDB存储引擎都是将数据和索引都存储到磁盘上的&#xff0c;当我们想查询表中的记录时&#xff0c;需要先把数据或者索引加载到内存中 然后再操作。这个从磁盘…

【合集一】每日一练30讲,轻松掌握Verilog语法

本原创教程由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;www.meyesemi.com) 第一练&#xff1a;如何区分&#xff1c;&#xff1d;表示的含义&#xff1f; 题目&#xff1a;请描述以下两种方法产…

[C/C++]数据结构 循环队列

前言: 队列是一种具有先进先出特性的结构,但是当数据出队列以后,前面的空间就无法再次利用了,循环队列就可以解决这个问题 一:概念及结构: 1.循环队列概念 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队…

CART算法解密:从原理到Python实现

本文深入探讨了CART&#xff08;分类与回归树&#xff09;算法的核心原理、实现方法以及应用场景。文章首先介绍了决策树的基础知识&#xff0c;然后详细解析了CART算法的工作机制&#xff0c;包括特征选择和树的构建。接着&#xff0c;通过Python和PyTorch的实例代码展示了CAR…

重生之我是一名程序员 37 ——C语言中的栈溢出问题

哈喽啊大家晚上好&#xff01; 今天呢给大家带来一个烧脑的知识——C语言中的栈溢出问题。那什么是栈溢出呢&#xff1f;栈溢出指的是当程序在执行函数调用时&#xff0c;为了保护函数的局部变量和返回地址&#xff0c;将这些数据存储在栈中。如果函数在函数调用时使用了过多的…

一站式企业快递管理平台使用教程

因公寄件在企业中重要性的提升&#xff0c;催生出了企业快递管理平台。为什么这么说呢&#xff1f; 随着经济和快递行业的发展&#xff0c;因公寄件在企业中成了一件“常事”&#xff0c;寄文件合同、发票、节假日慰问品、样品等等&#xff0c;这种情况之下&#xff0c;因公寄件…

HDX读卡器牛羊管理RFID设备品牌

半双工HDX&#xff08;Half Duplex&#xff09;技术是ISO11784/5中规定的另一种标签与读写器之间的通讯方式&#xff0c;与全双工工&#xff08;FDX&#xff09;相比&#xff0c;HDX通常识别能力更强&#xff0c;有更大的识别距离。在HDX读写器的射频场与HDX标签响应期间关闭&a…

1. git入门操作

1. git入门操作 1、基本名词解释 图片 名词含义index索引区&#xff0c;暂存区master分支名&#xff0c;每个仓库都有个master&#xff0c;它作为主分支。branch其他分支&#xff0c;我们可以把master分支上的代码拷贝一份&#xff0c;重新命名为其他分支名work space就是我…

深眸科技聚焦AI机器视觉检测,驱动3C电子行业集成创新实现新需求

随着消费的升级及国家政策的助推&#xff0c;国内3C电子市场不断扩大&#xff0c;行业实现高速发展。近年来&#xff0c;3C电子产品持续迭代&#xff0c;生产工艺也逐渐复杂化&#xff0c;相关生产线定位组装、零部件检测、整机产品检测等环节&#xff0c;亟需使用具备较强适应…

electerm 跨平台的终端 /ssh/sftp 客户端

文章目录 electerm功能特性主题配色 electerm 每个程序员基本都离开SSH链接工具,目前市场上好用的基本都是收费的 给大家推荐一款国人开发的开源链接工具https://github.com/electerm/electerm 到目前为止star已经9.5K了,非常受欢迎 功能特性 支持ssh,telnet,serialport,本地和…

Spring Cloud LoadBalancer 简单介绍与实战

前言 本文为SpringCloud的学习笔记&#xff0c;如有错误&#xff0c;希望各位高手能指出&#xff0c;主要介绍SpringCloudLoadBalancer的基本概念和实战 文章目录 前言什么是LoadBalancer负载均衡分类服务端负载均衡客户端负载均衡服务端负载均衡和客户端负载均衡的优缺点 常见…