当前位置: 首页 > news >正文

【C++】STL详解(十一)—— unordered_set、unordered_map的介绍及使用

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:C++学习
🎯长路漫漫浩浩,万事皆有期待

上一篇博客:【C++】STL详解(五)—— list的介绍及使用

文章目录

  • unordered系列关联式容器
    • unordered_set的介绍
      • unordered_set的使用
      • unordered_set接口的使用
      • unordered_multiset
    • unordered_map的介绍
    • unordered_map的使用
      • unordered_map的定义方式
      • unordered_map接口的使用
      • unordered_multimap
  • 总结:

unordered系列关联式容器

在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时的效率可达到O(logN),即最差情况下需要比较红黑树的高度次,当树中的结点非常多时,查询效率也不理想。最好的查询是,进行很少的比较次数就能够将元素找到,因此在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同。

unordered_set的介绍

unordered_set是不按特定顺序存储键值的关联式容器,其允许通过键值快速的索引到对应的元素。

在unordered_set中,元素的值同时也是唯一地标识它的key。

在内部,unordered_set中的元素没有按照任何特定的顺序排序,为了能在常数范围内找到指定的key,unordered_set将相同哈希值的键值放在相同的桶中。

unordered_set容器通过key访问单个元素要比set快,但它通常在遍历元素子集的范围迭代方面效率较低。

它的迭代器至少是前向迭代器。

unordered_set的使用

unordered_set的定义方式
方式一: 构造一个某类型的空容器。

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

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

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

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

string str("abcedf");
unordered_set<char> us3(str.begin(), str.end()); //构造string对象某段区间的复制品

unordered_set接口的使用

unordered_set当中常用的成员函数如下:

成员函数	功能
insert	插入指定元素
erase	删除指定元素
find	查找指定元素
size	获取容器中元素的个数
empty	判断容器是否为空
clear	清空容器
swap	交换两个容器中的数据
count	获取容器中指定元素值的元素个数

unordered_set当中迭代器相关函数如下:

成员函数	功能
begin	获取容器中第一个元素的正向迭代器
end	    获取容器中最后一个元素下一个位置的正向迭代器

使用示例:

#include <iostream>
#include <unordered_set>
using namespace std;int main()
{unordered_set<int> us;//插入元素(去重)us.insert(1);us.insert(4);us.insert(3);us.insert(3);us.insert(2);us.insert(2);us.insert(3);//遍历容器方式一(范围for)for (auto e : us){cout << e << " ";}cout << endl; //1 4 3 2//删除元素方式一us.erase(3);//删除元素方式二unordered_set<int>::iterator pos = us.find(1); //查找值为1的元素if (pos != us.end()){us.erase(pos);}//遍历容器方式二(迭代器遍历)unordered_set<int>::iterator it = us.begin();while (it != us.end()){cout << *it << " ";it++;}cout << endl; //4 2//容器中值为2的元素个数cout << us.count(2) << endl; //1//容器大小cout << us.size() << endl; //2//清空容器us.clear();//容器判空cout << us.empty() << endl; //1//交换两个容器的数据unordered_set<int> tmp{ 11, 22, 33, 44 };us.swap(tmp);for (auto e : us){cout << e << " ";}cout << endl; //11 22 33 44return 0;
}

unordered_multiset

unordered_multiset容器与unordered_set容器的底层数据结构是一样的,都是哈希表,其次,它们所提供的成员函数的接口都是基本一致的,这里就不再列举了,这两种容器唯一的区别就是,unordered_multiset容器允许键值冗余,即unordered_multiset容器当中存储的元素是可以重复的。

#include <iostream>
#include <unordered_set>
using namespace std;int main()
{unordered_multiset<int> ums;//插入元素(允许重复)ums.insert(1);ums.insert(4);ums.insert(3);ums.insert(3);ums.insert(2);ums.insert(2);ums.insert(3);for (auto e : ums){cout << e << " ";}cout << endl; //1 4 3 3 3 2 2return 0;
}

由于unordered_multiset容器允许键值冗余,因此该容器中成员函数find和count的意义与unordered_set容器中的也有所不同:

成员函数find 功能

unordered_set容器		返回键值为val的元素的迭代器
unordered_multiset容器	返回底层哈希表中第一个找到的键值为val的元素的迭代器

成员函数count 功能

unordered_set容器		键值为val的元素存在则返回1,不存在则返回0(find成员函数可替代)
unordered_multiset容器	返回键值为val的元素个数(find成员函数不可替代)

unordered_map的介绍

unordered_map是存储<key, value>键值对的关联式容器,其允许通过key值快速的索引到与其对应是value。

在unordered_map中,键值通常用于唯一地标识元素,而映射值是一个对象,其内容与此键关联。键和映射值的类型可能不同。

在内部,unordered_map没有对<key, value>按照任何特定的顺序排序,为了能在常数范围内找到key所对应的value,unordered_map将相同哈希值的键值对放在相同的桶中。

unordered_map容器通过key访问单个元素要比map快,但它通常在遍历元素子集的范围迭代方面效率较低。

unordered_map实现了直接访问操作符(operator[]),它允许使用key作为参数直接访问value。

它的迭代器至少是前向迭代器。

unordered_map的使用

unordered_map的定义方式

方式一: 指定key和value的类型构造一个空容器。

unordered_map<int, double> um1; //构造一个key为int类型,value为double类型的空容器

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

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

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

unordered_map<int, double> um3(um2.begin(), um2.end()); //使用迭代器拷贝构造um2容器某段区间的复制品

unordered_map接口的使用

unordered_map当中常用的成员函数如下:

成员函数	功能
insert	插入键值对
erase	删除指定key值的键值对
find	查找指定key值的键值对
size	获取容器中元素的个数
empty	判断容器是否为空
clear	清空容器
swap	交换两个容器中的数据
count	获取容器中指定key值的元素个数

除了上述的成员函数之外,unordered_map容器当中还实现了[ ]运算符重载函数,该重载函数的功能非常强大:

若当前容器中已有键值为key的键值对,则返回该键值对value的引用。
若当前容器中没有键值为key的键值对,则先插入键值对<key, value()>,然后再返回该键值对中value的引用。

unordered_map当中迭代器相关函数如下:

成员函数		功能
begin		获取容器中第一个元素的正向迭代器
end			获取容器中最后一个元素下一个位置的正向迭代器

使用示例:

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;int main()
{unordered_map<int, string> um;//插入键值对方式一:构造匿名对象插入um.insert(pair<int, string>(1, "one"));um.insert(pair<int, string>(2, "two"));um.insert(pair<int, string>(3, "three"));//遍历方式一:范围forfor (auto e : um){cout << e.first << "->" << e.second << " ";}cout << endl; //1->one 2->two 3->three//插入键值对方式二:调用make_pair函数模板插入um.insert(make_pair(4, "four"));um.insert(make_pair(5, "five"));um.insert(make_pair(6, "six"));//遍历方式二:迭代器遍历unordered_map<int, string>::iterator it = um.begin();while (it != um.end()){cout << it->first << "->" << it->second << " ";it++;}cout << endl; //1->one 2->two 3->three 4->four 5->five 6->six//插入键值对方式三:利用[]运算符重载函数进行插入(常用)um[7] = "seven";um[8] = "eight";um[9] = "nine";for (auto e : um){cout << e.first << "->" << e.second << " ";}cout << endl; //9->nine 1->one 2->two 3->three 4->four 5->five 6->six 7->seven 8->eight//删除键值对方式一:根据key值删除um.erase(5);//删除键值对方式二:根据迭代器删除unordered_map<int, string>::iterator pos = um.find(7); //查找键值为7的键值对if (pos != um.end()){um.erase(pos);}for (auto e : um){cout << e.first << "->" << e.second << " ";}cout << endl; //9->nine 1->one 2->two 3->three 4->four 6->six 8->eight//修改键值对方式一:通过find获得迭代器,通过迭代器修改pos = um.find(1);if (pos != um.end()){pos->second = "one/first";}//修改键值对方式二:利用[]运算符重载函数进行修改(常用)um[2] = "two/second";for (auto e : um){cout << e.first << "->" << e.second << " ";}cout << endl; //9->nine 1->one/first 2->two/second 3->three 4->four 6->six 8->eight//容器中key值为3的键值对的个数cout << um.count(3) << endl;//容器的大小cout << um.size() << endl;//清空容器um.clear();//容器判空cout << um.empty() << endl;//交换两个容器的数据unordered_map<int, string> tmp{ { 2021, "before" }, { 2022, "now" } };um.swap(tmp);for (auto e : um){cout << e.first << "->" << e.second << " ";}cout << endl; //2021->before 2022->nowreturn 0;
}

unordered_multimap

unordered_multimap容器与unordered_map容器的底层数据结构是一样的,都是哈希表,其次,它们所提供的成员函数的接口都是基本一致的,这里就不再列举了,这两种容器唯一的区别就是,unordered_multimap容器允许键值冗余,即unordered_multimap容器当中存储的键值对的key值是可以重复的。

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;int main()
{unordered_multimap<int, string> umm;//插入键值对(允许键值重复)umm.insert(make_pair(2022, "吃饭"));umm.insert(make_pair(2022, "睡觉"));umm.insert(make_pair(2022, "敲代码"));for (auto e : umm){cout << e.first << "->" << e.second << " ";}cout << endl; //2022->吃饭 2022->睡觉 2022->敲代码return 0;
}

由于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容器允许键值对的键值冗余,调用[ ]运算符重载函数时,应该返回键值为key的哪一个键值对的value的引用存在歧义,因此在unordered_multimap容器当中没有实现[ ]运算符重载函数。

总结:

今天我们比较详细地完成了 unordered_set、unordered_map的介绍及使用,了解了一些有关的底层原理。接下来,我们用哈希表封装出unordered_map和unordered_set。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

相关文章:

【C++】STL详解(十一)—— unordered_set、unordered_map的介绍及使用

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;C学习 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 上一篇博客&#xff1a;【C】STL…...

【C语言】动态通讯录(超详细)

通讯录是一个可以很好锻炼我们对结构体的使用&#xff0c;加深对结构体的理解&#xff0c;在为以后学习数据结构打下结实的基础 这里我们想设计一个有添加联系人&#xff0c;删除联系人&#xff0c;查找联系人&#xff0c;修改联系人&#xff0c;展示联系人&#xff0c;排序这几…...

Mac下docker安装MySQL8.0.34

学习并记录一下如何用docker部署MySQL 在Docker中搜索并下载MySQL8.0.x的最新版本 下载好后&#xff0c;在Images中就可以看到MySQL的镜像了 通过下面的命令也可以查看docker images启动镜像&#xff0c;使用下面的命令就可以启动镜像了docker run -itd --name mysql8.0.34 -…...

基于python编写的excel表格数据标记的exe文件

目录 一、需求&#xff1a; 二、思路&#xff1a; 三、工具 四、设计过程 &#xff08;一&#xff09;根据需要导入相关的图形界面库 &#xff08;二&#xff09;创建图形窗口 &#xff08;三&#xff09;标签设计 &#xff08;四&#xff09;方法按钮设计 &#xff0…...

acwing算法基础之基础算法--高精度加法算法

目录 1 知识点2 模板 1 知识点 大整数 大整数&#xff0c;它们的长度都为 1 0 6 10^6 106。大整数是指长度为 1 0 6 10^6 106的整数。 大整数 - 大整数 大整数 * 小整数 大整数 / 小整数 把大整数存储到向量中&#xff0c;需要考虑高位在前还是低位在前&#xff0c;低位在前…...

openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化:x86

文章目录 openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化&#xff1a;x8684.1 BIOS84.2 操作系统环境设置84.3 网络 openGauss学习笔记-84 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT部署服务器优化&#xff1a;x86 …...

二分查找:34. 在排序数组中查找元素的第一个和最后一个位置

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《算法》 文章目录 前言一、题目解析二、解题思路1. 暴力查找2. 一次二分查找 部分遍历3. 两次二分查找分别查找左右端点1.查找区间左端点2. 查找区间右端点 三、代码实现总结 前言 本篇文…...

javaee ssm框架项目整合thymeleaf2.0 更多thymeleaf标签用法 项目结构图

创建ssmthymeleaf项目 创建ssmthymeleaf项目参考此文 thymeleaf更多常用标签 <!DOCTYPE html> <html lang"en" xmlns:th"http://www.thymeleaf.org"> <head><meta charset"UTF-8"><title>Title</title> …...

lv7 嵌入式开发-网络编程开发 11 TCP管理与UDP协议

目录 1 TCP管理 1.1 三次握手 1.2 四次挥手 1.3 保活计时器 2 wireshark安装及实验 3.1 icmp协议抓包演示 3.2 tcp协议抓包演示 3 UDP协议 3.1 UDP 的主要特点&#xff1a; 4 练习 1 TCP管理 1.1 三次握手 TCP 建立连接的过程叫做握手。 采用三报文握手&#xff1…...

overleaf在线编辑工具使用教程

文章目录 1 用 orcid注册overleaf获取模板2 使用模板 1 用 orcid注册overleaf获取模板 通常来说&#xff0c;在期刊投稿网站information for author中找template 。下载压缩包后上传到over leaf中。 加入找不到官方模板&#xff0c;用overleaf中的 2 使用模板 .bib文件&…...

Python基础复习【第一弹】【黑马】

本篇是观看b站黑马视频所做的笔记第一弹&#xff0c;为1-98节。 b站-黑马Python # 1.Hello World print("Hello World")# 2.字面量 在代码中&#xff0c;被写下来固定的值# 3.字符串 print("python")# 4.单行注释 # 多行注释""" "&q…...

【Word】公式编辑器中连字符/减号等显示偏长/过长

问题 当公式编辑器中出现连字符的时候&#xff0c;连字符显示偏长&#xff0c;如下图所示&#xff1a; 方法 在连字符的前后加上双引号后即可解决连字符显示偏长的问题。 最终效果对比如下&#xff1a; 结语 Word的公式编辑器中&#xff0c;双引号内部的内容被当做普通…...

架构设计系列4:如何设计高性能架构

在架构设计系列1&#xff1a;什么是架构设计中&#xff0c;我们讲了架构设计的主要目的&#xff0c;是为了解决软件系统复杂度带来的问题&#xff0c;今天我们来聊聊软件系统复杂度的来源之一高性能。 一、什么是高性能架构&#xff1f; 要搞清楚什么是高性能架构&#xff0c…...

1392. 最长快乐前缀

链接&#xff1a; 1392. 最长快乐前缀 题解&#xff1a; class Solution { public:string longestPrefix(string s) {if (s.size() < 0) {return "";}int MOD 1e9 7;// 构建26的n次方&#xff0c;预处理std::vector<long> pow26(s.size());pow26[0] 1…...

【C++设计模式之备忘录模式:行为型】分析及示例

简介 备忘录模式&#xff08;Memento Pattern&#xff09;是一种行为型设计模式&#xff0c;它用于保存和恢复对象的状态。备忘录模式通过将对象的状态封装成一个备忘录&#xff08;Memento&#xff09;&#xff0c;并将备忘录保存在一个管理者&#xff08;Caretaker&#xff…...

数据结构与算法(四):哈希表

参考引用 Hello 算法 Github&#xff1a;hello-algo 1. 哈希表 1.1 哈希表概述 哈希表&#xff08;hash table&#xff09;&#xff0c;又称散列表&#xff0c;其通过建立键 key 与值 value 之间的映射&#xff0c;实现高效的元素查询 具体而言&#xff0c;向哈希表输入一个键…...

FFmpeg 命令:从入门到精通 | ffplay 播放控制选项

FFmpeg 命令&#xff1a;从入门到精通 | ffplay 播放控制选项 FFmpeg 命令&#xff1a;从入门到精通 | ffplay 播放控制选项选项表格图片 FFmpeg 命令&#xff1a;从入门到精通 | ffplay 播放控制选项 选项表格 项目说明Q&#xff0c;Esc退出播放F&#xff0c;鼠标左键双击全…...

代码随想录day59

647. 回文子串 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#…...

【小工具-生成合并文件】使用python实现2个excel文件根据主键合并生成csv文件

1 小工具说明 1.1 功能说明 一般来说&#xff0c;我们会先有一个老的文件&#xff0c;这个文件内容是定制好相关列的表格&#xff0c;作为每天的报告。 当下一天来的时候&#xff0c;需要根据新的报表文件和昨天的报表文件做一个合并&#xff0c;合并的时候就会出现有些事新增…...

【论文阅读】An Evaluation of Concurrency Control with One Thousand Cores

An Evaluation of Concurrency Control with One Thousand Cores Staring into the Abyss: An Evaluation of Concurrency Control with One Thousand Cores ABSTRACT 随着多核处理器的发展&#xff0c;一个芯片可能有几十乃至上百个core。在数百个线程并行运行的情况下&…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

Linux操作系统共享Windows操作系统的文件

目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项&#xff0c;设置文件夹共享为总是启用&#xff0c;点击添加&#xff0c;可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download&#xff08;这是我共享的文件夹&#xff09;&…...