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

news2024/11/15 18:00:43

目录

一、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中的元素构造set
	int 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;
	else
		cout << "键值为peach的元素已经存在:" << ret.first->first << "--->"
		<< ret.first->second << " 插入失败" << endl;
	// 删除key为"apple"的元素
	m.erase("apple");
	if (1 == m.count("apple"))
		cout << "apple还在" << endl;
	else
		cout << "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.coloradmin.cn/o/1813994.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣刷题--2843. 统计对称整数的数目【简单】

题目描述 给你两个正整数 low 和 high 。 对于一个由 2 * n 位数字组成的整数 x &#xff0c;如果其前 n 位数字之和与后 n 位数字之和相等&#xff0c;则认为这个数字是一个对称整数。 返回在 [low, high] 范围内的 对称整数的数目 。 示例 1&#xff1a; 输入&#xff1…

“大模型高考状元”花落谁家?高考前夜这个AI火了

“大模型高考元年”来了&#xff01;2024高考刚刚落幕&#xff0c;市面上的大模型几乎都被提溜出来&#xff0c;在公众围观下角逐“AI高考状元”。 就在高考前夜&#xff0c;有一家大模型公司放了大招。6月7日凌晨0点左右&#xff0c;阿里云发布通义千问第二代开源模型Qwen2。…

Spring:element-ui中的tree、树形结构的实现

一、三层架构代码 可能很多人都没写过关于tree的代码&#xff0c;今天我来演示一下&#xff0c;步骤很全&#xff0c;放心观看。 首先来看element-ui官网关于tree的示例&#xff1a; <el-tree :data"data" :props"defaultProps" node-click"hand…

利用Pandas数据过滤减少运算时间

当处理大型数据集时&#xff0c;使用 Pandas 可以提高数据处理的效率。Pandas 提供了强大的数据结构和功能&#xff0c;包括数据过滤、筛选、分组和聚合等&#xff0c;可以帮助大家快速减少运算时间。 1、问题背景 我有一个包含37456153行和3列的Pandas数据帧&#xff0c;其中…

利用泽攸科技原位TEM技术揭示真空击穿过程中电场与电极材料相互作用

在高能物理设备和许多其他设备中&#xff0c;真空击穿&#xff08;VBD&#xff09;现象对高能物理设备的性能造成了严重的阻碍&#xff0c;包括真空断路器、X射线源、聚变反应堆以及粒子加速器等。然而由于对导致VBD的机制缺乏足够的科学理解&#xff0c;这些问题至今无法得到缓…

【stable diffusion】ComfyUI扩展安装以及点开后页面空白问题解决办法

扩展安装 虽然大家都推荐将扩展包直接放到extension文件夹的方式,但我还是推荐直接在sd webui的扩展处下载,酱紫比较好维护一点,我个人感觉。 按照上图顺序点击会出现”URLError: <urlopen error [Errno 11004] getaddrinfo failed>”的情况,问题不大,打开一个git…

隐藏字符串中间字符,一个公共方法解决产品的所有设想

说到隐藏字符串中间字符&#xff0c;就是 13833321212 给用户显示成 “138***1212” 这样子呗&#xff0c;你是不是也是这样认为的。我刚开始拿到需求&#xff0c;就是这样认为的。但是越到后来发现越不对劲儿。来看看我的隐藏历程吧。 一 产品来了 1 加星第一步 产品刚开始…

ThinkBook 16 2024 Ubuntu 触控板问题解决

sudo insmod goodix-gt7868q.ko sudo cp local-overrides.quirks /etc/libinput/local-overrides.quirks sudo systemctl restart gdm 有偿解决&#xff0c;无效退款

R语言使用survivalsvm包进行支持向量机生存分析

1995年VAPINK 等人在统计学习理论的基础上提出了一种模式识别的新方法—支持向量机 。它根据有限的样本信息在模型的复杂性和学习能力之间寻求一种最佳折衷。 以期获得最好的泛化能力.支持向量机的理论基础决定了它最终求得的是全局最优值而不是局部极小值,从而也保证了它对未知…

LeetCode题练习与总结:二叉树中的最大路径和--124

一、题目描述 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点 ro…

swift微调牧歌数据电商多模态大语言模型

大规模中文多模态评测基准MUGE_数据集-阿里云天池多模态理解和生成评估挑战榜(MUGE)是由阿里巴巴达摩院智能计算实验室发起,由阿里云天池平台承办,并由浙江大学、清华大学等单位共同协办。 Mhttps://tianchi.aliyun.com/dataset/107332微调的是牧歌数据集,结果都不好,记录…

C语言学习系列:笔记列表

1&#xff0c;精神建设&#xff1a;为什么要学C语言以及如何学习C语言 2&#xff0c;C语言学习系列&#xff1a;GCC编译器Windows版本MinGW-w64的安装教程 3&#xff0c;C语言学习系列&#xff1a;初识C语言 4&#xff0c;C语言入门学习系列&#xff1a;基本语法

工业和信息化部电子工业标准化研究院人工智能从业人员“计算机视觉设计开发工程师”专项培训(第四期)

注&#xff1a;若出现无法显示完全的情况&#xff0c;可搜索“人工智能技术与咨询”查看完整文章 声明: 公众号转载的文章及图片出于非商业性的教育和科研目的供大家参考和探讨&#xff0c;并不意味着支持其观点或证实其内容的真实性。版权归原作者所有&#xff0c;如转载稿涉及…

面试-NLP八股文

机器学习 交叉熵损失&#xff1a; L − ( y l o g ( y ^ ) ( 1 − y ) l o g ( 1 − ( y ^ ) ) L-(ylog(\hat{y}) (1-y)log(1-(\hat{y})) L−(ylog(y^​)(1−y)log(1−(y^​))均方误差&#xff1a; L 1 n ∑ i 1 n ( y i − y ^ i ) 2 L \frac{1}{n}\sum\limits_{i1}^{n}…

软件3班20240612

加粗样式 maven 根据的使用案例 package com.yanyu;public class Demo02 {// 设置 一个 求 两个数 的 和 的 方法 sumpublic void sum(int num1, int mum2) {System.out.println("两个数 的 和 是 &#xff1a;" (num1 mum2));} }import com…

盲盒小程序推广与运营策略的挑战

随着盲盒经济的兴起&#xff0c;越来越多的商家开始关注并尝试开发盲盒小程序。然而&#xff0c;在推广和运营盲盒小程序的过程中&#xff0c;我们也不可避免地会遇到一些挑战。下面&#xff0c;我将就用户获取、留存以及活跃度提升等方面&#xff0c;探讨这些挑战及可能的应对…

常用环境部署(十四)——Docker部署MinIO

一、安装Docker及Docker-compose https://blog.csdn.net/wd520521/article/details/112609796 二、Docker-compose部署MinIO 1、在服务器创建/data/minio目录 mkdir -p /data/minio 2、 docker-compose.yml脚本创建 vim /data/minio/docker-compose.yml &#xff08;1&a…

使用易备数据备份软件,简单快速地备份 Oracle 数据库

易备数据备份软件能够以简单高效的方式&#xff0c;实现对 Oracle 数据库的保护。 易备数据备份软件数据库备份功能的关键特性 自动保护网站数据库及应用程序实时备份&#xff0c;不需要任何中断或数据库锁定基于日期和时间的备份任务计划可恢复到一个已存在的数据库或创建一…

【java计算机毕设】图书商城管理系统MySQL springboot vue html maven送文档

1项目功能介绍 【java计算机毕设】图书商城管理系统 Java Spring Boot vue HTML MySQL 赠送文档 PPT 2项目简介 系统功能&#xff1a; 图书商城管理系统包括管理员和用户两种角色。 管理员的功能包括在个人中心修改个人信息&#xff0c;以及在基础数据管理中管理会员等级类型和…

STM89C51开发学习1

环境安装&#xff1a; 使用Keil uVision4环境进行对51单片机的学习。 在进行使用之前先用keygen进行对软件的破解防止后续发生不必要的问题。 开发环境下载完毕后&#xff0c;检查电脑是否有串口驱动&#xff08;可以在网上下载&#xff09; CH340驱动。 安装stcai-…