C++的STL 中 set.map multiset.multimap 学习使用详细讲解(含配套OJ题练习使用详细解答)

目录

一、set

1.set的介绍

2.set的使用

2.1 set的模板参数列表

2.2 set的构造

2.3 set的迭代器

2.4 set的容量

2.5 set的修改操作

2.6 set的使用举例

二、map

1.map的介绍

2.map的使用

2.1 map的模板参数说明

2.2 map的构造

2.3 map的迭代器

2.4 map的容量与元素访问

2.5 map中元素的修改

2.6 map的使用举例

三、multiset

1.multiset的介绍

2.multiset的使用

四、multimap

1.multimap的介绍

2.multimap的使用

五、OJ题练习使用

1.前K个高频单词

2.两个数组的交集

六、完结撒❀


一、set

1.set的介绍

set文档介绍

翻译:
1. set是按照一定次序存储元素的容器。
2. 在 set 中,元素的 value 也标识它 (value 就是 key ,类型为 T) ,并且每个 value 必须是唯一的。
set中的元素不能在容器中修改( 元素总是 const) ,但是可以从容器中插入或删除它们。
3.在内部, set 中的元素总是按照其内部比较对象 ( 类型比较 ) 所指示的特定严格弱排序准则进行 排序。
4. set容器通过 key 访问单个元素的速度通常比 unordered_set 容器慢,但它们允许根据顺序对
子集进行直接迭代。
5. set在底层是用二叉搜索树 ( 红黑树 ) 实现的。
注意:
1. map/multimap 不同, map/multimap 中存储的是真正的键值对 <key, value> set 中只放
value ,但在底层实际存放的是由 <value, value> 构成的键值对。
2. set 中插入元素时,只需要插入 value 即可,不需要构造键值对。
3. set 中的元素不可以重复 ( 因此可以使用 set 进行去重 )
4. 使用 set 的迭代器遍历 set 中的元素,可以得到有序序列
5. set 中的元素默认按照小于来比较
6. set 中查找某个元素,时间复杂度为: log2 n
7. set 中的元素不允许修改 ( 为什么 ? --- 麻烦 排序的维护,唯一性的维护,时间复杂度的维护)
8. set 中的底层使用二叉搜索树 ( 红黑树 ) 来实现。

2.set的使用

2.1 set的模板参数列表

T: set 中存放元素的类型,实际在底层存储 <value, value> 的键值对。
Compare set 中元素默认按照小于来比较
Alloc set 中元素空间的管理方式,使用 STL 提供的空间配置器管理

2.2 set的构造

函数声明功能介绍
set(const Compare& comp = Compare(),const Allocstor& = Allocator());构造空的set
set(InputIterator first,InputIterator last,const Compare& comp = Compare(),const Allocator& = Allocator());用[first,last)区间中的元素构造set
set(const set<Key,Compare,Allocator>& x);set的拷贝构造

2.3 set的迭代器

函数声明功能介绍
iterator begin()返回set中起始位置元素的迭代器
iterator end()
返回 set 中最后一个元素后面的迭代器
const_iterator cbegin()
const
返回 set 中起始位置元素的 const 迭代器
const_iterator cend() const
返回 set 中最后一个元素后面的 const 迭代器
reverse_iterator rbegin()
返回 set 第一个元素的反向迭代器,即 end
reverse_iterator rend()
返回 set 最后一个元素下一个位置的反向迭代器,
rbegin
const_reverse_iterator
crbegin() const
返回 set 第一个元素的反向 const 迭代器,即 cend
const_reverse_iterator
crend() const
返回 set 最后一个元素下一个位置的反向 const
代器,即 crbegin

2.4 set的容量

函数声明功能介绍
bool empty() const检测set是否为空,空返回true,否则返回false
size_type size() const返回set中有效元素个数

2.5 set的修改操作

函数声明功能介绍
pair<iterator,bool> insert (const value_type& x )
set 中插入元素 x ,实际插入的是 <x, x> 构成的
键值对,如果插入成功,返回 < 该元素在 set 中的
位置, true>, 如果插入失败,说明 x set 中已经
存在,返回 <x set 中的位置, false>
void erase ( iterator position )
删除 set position 位置上的元素
size_type erase ( const key_type& x )
删除 set 中值为 x 的元素,返回删除的元素的个数
void erase ( iterator first, iterator last )
删除 set [first, last) 区间中的元素
void swap ( set<Key,Compare,Allocator>& st);
交换 set 中的元素
void clear ( )
set 中的元素清空
iterator find ( const key_type& x ) const
返回 set 中值为 x 的元素的位置,没有找到返回end()
size_type count ( const key_type& x ) const
返回 set 中值为 x 的元素的个数

2.6 set的使用举例

#include <set>
void TestSet()
{// 用数组array中的元素构造setint array[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0, 1, 3, 5, 7, 9, 2, 4,
6, 8, 0 };set<int> s(array, array + sizeof(array) / sizeof(array[0]));cout << s.size() << endl;// 正向打印set中的元素,从打印结果中可以看出:set可去重for (auto& e : s)cout << e << " ";cout << endl;// 使用迭代器逆向打印set中的元素for (auto it = s.rbegin(); it != s.rend(); ++it)cout << *it << " ";cout << endl;// set中值为3的元素出现了几次cout << s.count(3) << endl;
}

二、map

1.map的介绍

map的文档介绍

翻译:
1.map是关联容器,它按照特定的次序 ( 按照 key 来比较 ) 存储由键值 key 和值 value 组合而成的元 素。
2. map 中,键值 key 通常用于排序和唯一的标识元素,而值 value 中存储与此键值 key 关联的
内容。键值 key 和值 value 的类型可能不同,并且在 map 的内部, key value 通过成员类型
value_type 绑定在一起,为其取别名称为 pair: typedef pair<const key, T> value_type;
3. 在内部, map 中的元素总是按照键值 key 进行比较排序的。
4.map 中通过键值访问单个元素的速度通常比 unordered_map 容器慢,但 map 允许根据顺序
对元素进行直接迭代 ( 即对 map 中的元素进行迭代时,可以得到一个有序的序列 )
5.map 支持下标访问符,即在 [ ] 中放入 key ,就可以找到与 key 对应的 value
6.map 通常被实现为二叉搜索树 ( 更准确的说:平衡二叉搜索树 ( 红黑树 ))

2.map的使用

2.1 map的模板参数说明

key: 键值对中 key 的类型
T : 键值对中 value 的类型
Compare: 比较器的类型, map 中的元素是按照 key 来比较的,缺省情况下按照小于来比
较,一般情况下 ( 内置类型元素 ) 该参数不需要传递,如果无法比较时 ( 自定义类型 ) ,需要用户
自己显式传递比较规则 ( 一般情况下按照函数指针或者仿函数来传递 )
Alloc :通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的
空间配置器
注意:在使用 map 时,需要包含头文件。

2.2 map的构造

函数声明功能介绍
map()构造一个空的map

2.3 map的迭代器

函数声明功能介绍
begin()和end()
begin: 首元素的位置, end 最后一个元素的下一个位置
cbegin()和cend()
begin end 意义相同,但 cbegin cend 所指向的元素不
能修改
rbegin()和rend()
反向迭代器, rbegin end 位置, rend begin 位置,其
++ -- 操作与 begin end 操作移动相反
crbegin()和crend()
rbegin rend 位置相同,操作相同,但 crbegin crend
指向的元素不能修改

2.4 map的容量与元素访问

函数声明功能介绍
bool empty ( ) const
检测 map 中的元素是否为空,是返回
true ,否则返回 false
size_type size() const
返回 map 中有效元素的个数
mapped_type& operator[] (const
key_type& k)
返回 key 对应的 value
问题:当 key 不在 map 中时,通过 operator 获取对应 value 时会发生什么问题?

注意:在元素访问时,有一个与 operator[] 类似的操作 at()( 该函数不常用 ) 函数,都是通过
key 找到与 key 对应的 value 然后返回其引用,不同的是: key 不存在时, operator[] 用默认
value key 构造键值对然后插入,返回该默认 value at() 函数直接抛异常

2.5 map中元素的修改

函数声明功能简介
pair<iterator,bool> insert (const value_type& x)
map 中插入键值对 x ,注意 x 是一个键值 对,返回值也是键值对: iterator 代表新插入 元素的位置, bool 代表释放插入成功
void erase ( iterator position )
删除 position 位置上的元素
size_type erase ( const key_type& x )
删除键值为 x 的元素
void erase ( iterator first, iterator last )
删除 [first, last) 区间中的元素
void swap ( map<Key,T,Compare,Allocator>& mp)
交换两个 map 中的元素
void clear ( )
map 中的元素清空
iterator find ( const key_type& x )
map 中插入 key x 的元素,找到返回该元 素的位置的迭代器,否则返回 end
const_iterator find ( const key_type& x ) const
map 中插入 key x 的元素,找到返回该元 素的位置的 const 迭代器,否则返回 cend
size_type count ( const key_type& x ) const
返回 key x 的键值在 map 中的个数,注意 map key 是唯一的,因此该函数的返回值 要么为 0 ,要么为 1 ,因此也可以用该函数来
检测一个 key 是否在 map

2.6 map的使用举例

#include <string>
#include <map>
void TestMap()
{map<string, string> m;// 向map中插入元素的方式:// 将键值对<"peach","桃子">插入map中,用pair直接来构造键值对m.insert(pair<string, string>("peach", "桃子"));// 将键值对<"peach","桃子">插入map中,用make_pair函数来构造键值对m.insert(make_pair("banan", "香蕉"));// 借用operator[]向map中插入元素/*operator[]的原理是:用<key, T()>构造一个键值对,然后调用insert()函数将该键值对插入到map中如果key已经存在,插入失败,insert函数返回该key所在位置的迭代器如果key不存在,插入成功,insert函数返回新插入元素所在位置的迭代器operator[]函数最后将insert返回值键值对中的value返回*/// 将<"apple", "">插入map中,插入成功,返回value的引用,将“苹果”赋值给该引用结果,m["apple"] = "苹果";// key不存在时抛异常//m.at("waterme") = "水蜜桃";cout << m.size() << endl;// 用迭代器去遍历map中的元素,可以得到一个按照key排序的序列for (auto& e : m)cout << e.first << "--->" << e.second << endl;cout << endl;// map中的键值对key一定是唯一的,如果key存在将插入失败auto ret = m.insert(make_pair("peach", "桃色"));if (ret.second)cout << "<peach, 桃色>不在map中, 已经插入" << endl;elsecout << "键值为peach的元素已经存在:" << ret.first->first << "--->"<< ret.first->second << " 插入失败" << endl;// 删除key为"apple"的元素m.erase("apple");if (1 == m.count("apple"))cout << "apple还在" << endl;elsecout << "apple被吃了" << endl;
}
【总结】
1. map 中的的元素是键值对
2. map 中的 key 是唯一的,并且不能修改
3. 默认按照小于的方式对 key 进行比较
4. map 中的元素如果用迭代器去遍历,可以得到一个有序的序列
5. map 的底层为平衡搜索树 ( 红黑树 ) ,查找效率比较高 O(log_2 N)
6. 支持 [] 操作符, operator[] 中实际进行插入查找。

三、multiset

1.multiset的介绍

multiset文档介绍

[ 翻译 ]
1. multiset 是按照特定顺序存储元素的容器,其中元素是可以重复的。
2. multiset 中,元素的 value 也会识别它 ( 因为 multiset 中本身存储的就是 <value, value> 组成
的键值对,因此 value 本身就是 key key 就是 value ,类型为 T). multiset 元素的值不能在容器
中进行修改 ( 因为元素总是 const ) ,但可以从容器中插入或删除。
3. 在内部, multiset 中的元素总是按照其内部比较规则 ( 类型比较 ) 所指示的特定严格弱排序准则进行排序。
4. multiset 容器通过 key 访问单个元素的速度通常比 unordered_multiset 容器慢,但当使用迭
代器遍历时会得到一个有序序列。
5. multiset 底层结构为二叉搜索树 ( 红黑树 )。
注意:
1. multiset 中在底层中存储的是 <value, value> 的键值对
2. multiset 的插入接口中只需要插入即可
3. set 的区别是, multiset 中的元素可以重复, set 是中 value 是唯一的
4. 使用迭代器对 multiset 中的元素进行遍历,可以得到有序的序列
5. multiset 中的元素不能修改
6. multiset 中找某个元素,时间复杂度为 O(log_2 N)
7. multiset 的作用:可以对元素进行排序

2.multiset的使用

此处只简单演示 set multiset 的不同,其他接口与 set 相同,可参考 set
#include <set>
void TestSet()
{int array[] = { 2, 1, 3, 9, 6, 0, 5, 8, 4, 7 };// 注意:multiset在底层实际存储的是<int, int>的键值对multiset<int> s(array, array + sizeof(array) / sizeof(array[0]));for (auto& e : s)cout << e << " ";cout << endl;return 0;
}

四、multimap

1.multimap的介绍

multimap文档链接

翻译:
1. Multimaps 是关联式容器,它按照特定的顺序,存储由 key value 映射成的键值对 <key,
value> ,其中多个键值对之间的 key 是可以重复的
2. multimap 中,通常按照 key 排序和唯一地标识元素,而映射的 value 存储与 key 关联的内
容。 key value 的类型可能不同,通过 multimap 内部的成员类型 value_type 组合在一起,
value_type 是组合 key value 的键值对 :
typedef pair<const Key, T> value_type;
3. 在内部, multimap 中的元素总是通过其内部比较对象,按照指定的特定严格弱排序标准对
key 进行排序的。
4. multimap 通过 key 访问单个元素的速度通常比 unordered_multimap 容器慢,但是使用迭代
器直接遍历 multimap 中的元素可以得到关于 key 有序的序列。
5. multimap 在底层用二叉搜索树 ( 红黑树 ) 来实现。
注意: multimap map 的唯一不同就是: map 中的 key 是唯一的,而 multimap key 是可以
重复的

2.multimap的使用

multimap 中的接口可以参考 map ,功能都是类似的。
注意:
1. multimap 中的 key 是可以重复的。
2. multimap 中的元素默认将 key 按照小于来比较
3. multimap 中没有重载 operator[] 操作 ( 可思考下为什么 ?) 。(多个key与value没有形成映射关系)
4. 使用时与 map 包含的头文件相同。

 五、OJ题练习使用

1.前K个高频单词

题目:

基本思路:

使用map将所有单词出现的次数进行存储,在使用vector进行排序,再将前K个push_back到新的vector里面进行返回。

解题代码:

class Solution {
public:struct kvCom{bool operator()(const pair<string,int> V1,const pair<string,int> V2){return (V1.second > V2.second) || (V1.second == V2.second && V1.first < V2.first);}};vector<string> topKFrequent(vector<string>& words, int k) {map<string,int> CountMap;for(auto& e : words){CountMap[e]++;}//按照int排序vector<pair<string,int>> v(CountMap.begin(),CountMap.end()); //stable_sort(v.begin(),v.end(),kvCom());sort(v.begin(),v.end(),kvCom());vector<string> vs;for(size_t i=0; i<k;i++){//cout<<v[i].first<<":"<<v[i].second<<endl;vs.push_back(v[i].first);}return vs;}
};

 2.两个数组的交集

题目:

基本思路:
通过将两个数组分别存进两个set里面(这一步也完成了去重,防止出现多个交集),再用一个vector进行存储返回,之后在其中一个set中查找是否存在另一个set中的值,若存在则push_back到vector中,循环操作,最后将vector进行返回。

解题代码:

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {set<int> s1(nums1.begin(),nums1.end());//已经完成去重工作set<int> s2(nums2.begin(),nums2.end());vector<int> v;for(auto e : s1){auto ret = s2.find(e);if(ret != s2.end()){v.push_back(*ret);}}return v;}
};

六、完结撒❀

如果以上内容对你有帮助不妨点赞支持一下,以后还会分享更多编程知识,我们一起进步。
最后我想讲的是,据说点赞的都能找到漂亮女朋友❤

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

API测试工具

apifox 微信扫描登录 不推荐&#xff1a; Download Postman

QT creator c动态链接库的创建与调用

QT creator c动态链接库的创建与调用 QT5.15.2 1.创建dll项目 确保两类型选择正确 2.选择MinGW 64-bit 3.点击完成 pro文件参考&#xff1a; QT - guiTEMPLATE lib DEFINES QT_DLL_DEMO_LIBRARYCONFIG c17# You can make your code fail to compile if it uses deprecat…

Flutter 使用ffigen生成ffmpeg的dart接口

Flutter视频渲染系列 第一章 Android使用Texture渲染视频 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频 第四章 全平台FFICustomPainter渲染视频 第五章 Windows使用Native窗口渲染视频 第六章 桌面端使用texture_rgba_renderer渲染视频 第七章 使用ff…

以sqlilabs靶场为例,讲解SQL注入攻击原理【54-65关】

【Less-54】 与前面的题目不同是&#xff0c;这里只能提交10次&#xff0c;一旦提交超过十次&#xff0c;数据会重新刷新&#xff0c;所有的步骤需要重来一次。 解题步骤&#xff1a; 根据测试&#xff0c;使用的是单引号闭合。 # 判断字段的数量 ?id1 order by 3 -- aaa# …

.NET MAUI 了解MVVM

MVVM 模式中有三个核心组件&#xff1a;模型、视图和视图模型。 每个组件的用途不同。 下图显示了这三个组件之间的关系。 视图 视图负责定义用户在屏幕上看到的结构、布局和外观。 理想情况下&#xff0c;每个视图在 XAML 中定义&#xff0c;代码隐藏有限&#xff0c;不包含业…

(论文翻译)Coordinate Attention for Efficient Mobile Network Design(坐标注意力 CVPR2021)

Coordinate Attention for Efficient Mobile Network Design&#xff08;CVPR2021&#xff09; 文章目录 Coordinate Attention for Efficient Mobile Network Design&#xff08;CVPR2021&#xff09;摘要1.引言2.相关工作3.方法&#xff1a;Coordinate Attention3.1.Revisit …

RHEL8/Centos8 install for PXE

PXE介绍 PXE&#xff08;Preboot Execution Environment&#xff09;是预引导执行环境的缩写。它是由Intel设计的&#xff0c;允许客户端计算机通过网络从服务器上加载操作系统镜像。PXE通常用于大规模部署操作系统&#xff0c;例如在企业或学校环境中。 PXE工作流程如下&…

C++ | Leetcode C++题解之第139题单词拆分

题目&#xff1a; 题解&#xff1a; class Solution { public:bool wordBreak(string s, vector<string>& wordDict) {auto wordDictSet unordered_set <string> ();for (auto word: wordDict) {wordDictSet.insert(word);}auto dp vector <bool> (s.…

【el-tooltips改造】Vue实现文本溢出才显示el-tooltip,否则不显示el-tooltips

实现原理&#xff1a; 使用disabled属性控制el-tooltip的content显示与隐藏&#xff1b; 目标&#xff1a; 1行省略、多行省略、可缩放页面内的文本省略都有效。 实现方式&#xff1a; 1、自定义全局指令&#xff0c;tooltipAutoShow.js代码如下&#xff08;参考的el-table中的…

04 架构核心技术之分布式消息队列

本课时的主题是分布式消息队列&#xff0c;分布式消息队列的知识结构如下图。 本课时主要介绍以下内容。 同步架构和异步架构的区别。异步架构的主要组成部分&#xff1a;消息生产者、消息消费者、分布式消息队列。异步架构的两种主要模型&#xff1a;点对点模型和发布订阅模型…

C# 异步方法async / await 任务超时处理

一、需求 如果调用一个异步方法后&#xff0c;一直不给返回值结果怎么办呢&#xff1f;这就涉及到怎么取消任务了。 二、Task取消任务 static CancellationTokenSource source new CancellationTokenSource();static void Main(string[] args){Task.Run(() >{for (int i …

【基于C++与OpenCV实现魔方图像识别和还原算法】施工总览图

文章目录 主要效果展示思维导图魔方还原算法 本系列博客长期更新&#xff0c;分为两大部分 OpenCV实现魔方六面识别 C编写科先巴二阶段还原算法实现三阶魔方的还原 主要效果展示 摄像头识别六面 3D图像构建&#xff0c;提供还原公式 动画演示还原过程 思维导图 魔方还原算法 参…

PowerDesigner导入Excel模板生成数据表

PowerDesigner导入Excel模板生成数据表 1.准备好需要导入的Excel表结构数据,模板内容如下图所示 2.打开PowerDesigner,新建一个physical data model文件,填入文件名称,选择数据库类型 3.点击Tools|Execute Commands|Edit/Run Script菜单或按下快捷键Ctrl Shift X打开脚本窗口…

免费开源图片转文字识别软件:Umi-OCR

目录 1.介绍 2.项目亮点 3.项目功能&#xff08;已实现&#xff09; 4.功能体验 5.项目集成&#xff08;调用接口&#xff09; 6.项目地址 1.介绍 Umi-OCR&#xff1a;免费&#xff0c;开源&#xff0c;可批量的离线OCR软件&#xff0c;目前适用于 Windows7 x64 及以上。…

【机器人和人工智能——自主巡航赛项】进阶篇

文章目录 案例要求创建地图rviz仿真 保存地图坐标点定位识别训练主逻辑理解语音播报模块匹配二维码识别多点导航讲解视频其余篇章 案例要求 创建地图 ./1-gmapping.sh 把多个launch文件融合在sh文件里面 rviz仿真 rviz是rose集成的可视化界面&#xff0c;查看机器人的各项数…

深度学习:如何静悄悄地改变我们的日常生活

深度学习 深度学习&#xff1a;如何静悄悄地改变我们的日常生活一、消费电子产品智能手机与个人助理娱乐与社交媒体 二、医疗健康三、汽车与交通四、公共安全五、总结 深度学习&#xff1a;如何静悄悄地改变我们的日常生活 在近年来&#xff0c;深度学习技术因其强大的数据处理…

Java——数组排序和查找

一、排序介绍 1、排序的概念 排序是将多个数据按照指定的顺序进行排列的过程。 2、排序的种类 排序可以分为两大类&#xff1a;内部排序和外部排序。 3、内部排序和外部排序 1&#xff09;内部排序 内部排序是指数据在内存中进行排序&#xff0c;适用于数据量较小的情况…

快速入门Linux及使用VSCode远程连接Linux服务器

在当前的技术环境中&#xff0c;Linux操作系统因其强大的功能和灵活性而广受欢迎。无论你是开发人员、系统管理员还是技术爱好者&#xff0c;学习Linux都是提升技术技能的重要一步。本文将介绍如何快速入门Linux&#xff0c;并使用Visual Studio Code&#xff08;VSCode&#x…

LabVIEW储油罐监控系统

LabVIEW储油罐监控系统 介绍了基于LabVIEW的储油罐监控系统的设计与实施。系统通过集成传感器技术和虚拟仪器技术&#xff0c;实现对储油罐内液位和温度的实时监控&#xff0c;提高了油罐监管的数字化和智能化水平&#xff0c;有效增强了油库安全管理的能力。 项目背景 随着…

【vector模拟实现】附加代码讲解

vector模拟实现 一、看源代码简单实现1. push_backcapacity&#xff08;容量&#xff09;sizereserve&#xff08;扩容&#xff09;operator[ ] &#xff08;元素访问&#xff09; 2. pop_back3. itorator&#xff08;迭代器&#xff09;4.insert & erase &#xff08;头插…