C C++最全【C++】map和set的使用_linux c+,2024年阿里C C++岗面试必问

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

3.1. map的介绍

3.2. map的使用

3.3. multimap的介绍

3.4. multimap的使用


1. 内容补充

1.1. 序列式容器与关联式容器

我们已经接触过STL中的部分容器,比如:vector、list、deque、forward_list等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身,其元素与元素之间并没有什么关联性。

关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据查找时比序列式容器效率更高 。

1.2. 键值对

用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息 。

其在SGI版本中的定义为:

template <class T1, class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
	T1 first;
	T2 second;
	pair(): first(T1()), second(T2())
	{}
	pair(const T1& a, const T2& b): first(a), second(b)
	{}
};

1.3. 树形结构的关联式容器

根据应用场景的不桶,STL总共实现了两种不同结构的管理式容器:树型结构与哈希结构。树型结构的关联式容器主要有四种:map、set、multimap、multiset。这四种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列。

2. set的使用

2.1. set的介绍

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中查找某个元素,时间复杂度为:log n
  7. set中的元素不允许修改
  8. set中的底层使用二叉搜索树(红黑树)来实现

2.2. set的使用

Compare:仿函数,set中元素的比较方式。

构造函数:

插入:

insert 重载了三种插入方法,值、迭代器位置、迭代器区间,这里演示最常用的值插入。

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


void test_set()
{
	set<int> myset;
	myset.insert(10);
	myset.insert(3);
	myset.insert(7);
	myset.insert(1);
	myset.insert(5);
	myset.insert(5); // 插入重复元素,会插入失败

	set<int>::iterator it = myset.begin(); 
	while (it != myset.end()) // 迭代器遍历:中序
	{
		cout << *it << " ";
		++it;
	}

}

通过上面的结果,其实set的功能也就体现出来了,就是 排序+去重。后面刷题中回很常用。

删除:

erase 也重载了三种方法:

删除迭代器(必须要求迭代器有效,一般配合find使用)、

删除值(有这个值就删除,没有也不会报错,底层其实就是封装了迭代器删除的过程,返回值为删除元素个数)、

删除迭代器区间。

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


void test_set()
{
	set<int> myset;
	myset.insert(10);
	myset.insert(3);
	myset.insert(7);
	myset.insert(1);
	myset.insert(5);
	myset.insert(5);

	set<int>::iterator it = myset.begin();
	while (it != myset.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	// 通过迭代器删除3
	set<int>::iterator pos = myset.find(3);
	if (pos != myset.end())
	{
		myset.erase(pos);
	}
	for (auto e : myset)
	{
		cout << e << " ";
	}
	cout << endl;

	// 通过值删除10
	myset.erase(10);
	for (auto e : myset)
	{
		cout << e << " ";
	}
	cout << endl;
}

2.3. multiset的介绍

multiset 的特点:

  1. multiset中在底层中存储的是<value, value>的键值对
  2. mtltiset的插入接口中只需要插入即可
  3. 与set的区别是,multiset中的元素可以重复,set是中value是唯一的
  4. 使用迭代器对multiset中的元素进行遍历,可以得到有序的序列
  5. multiset中的元素不能修改
  6. 在multiset中找某个元素,时间复杂度为: log n
  7. multiset的作用:可以对元素进行排序

2.4. multiset的使用

multiset的使用与set几乎一摸一样,唯一不同就是multiset中允许插入重复值。

void test_multiset()
{
	multiset<int> myset;
	myset.insert(1);
	myset.insert(1);
	myset.insert(5);
	myset.insert(5);
	myset.insert(5);
	myset.insert(5);
	myset.insert(3);
	myset.insert(2);

	for (auto e : myset)
	{
		cout << e << " ";
	}
	cout << endl;

	multiset<int>::iterator pos = myset.find(1); // 当find的val有多个值时,返回中序第一个val值所在节点的迭代器
	if (pos != myset.end())
	{
		myset.erase(pos);
	}

	int n = myset.erase(5); // 删除所有的5,并返回删除个数
	cout << n << endl;
	for (auto e : myset)
	{
		cout << e << " ";
	}
	cout << endl;
}

3.map的使用

3.1. map的介绍

map的特点:

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

3.2. map的使用

key: 键值对中key的类型

T: 键值对中value的类型

Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)

Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器

map 在使用使用上的最大区别就是多了一个模板参数V(文档中给的是T),且使用时是将KV两个模板参数封装在了pair里面。

pair的第一个参数(first)是K,第二个参数(second)是V。

插入:

value_type:键值对,可以通过pair本身提供的构造函数初始化。

pair键值对也可以通过make_pair函数构造,一般常用这种方法。(make_pair:其实是对pair匿名构造的封装,并且可以自动推导类型)

void test_map()
{
	map<string, string> m;
	pair<string, string>kv1("left", "左");
	m.insert(kv1);
	m.insert(pair<string, string>("right", "右")); // 匿名对象构造
	m.insert(make_pair("one", "1"));
	m.insert(make_pair("two", "2"));
	m.insert(make_pair("three", "3"));
	for (auto& e : m)
	{
		cout << e.first << ":" << e.second << endl; // 不能直接打印pair键值对,分开打印
	}
}

删除:

可以通过某个位置的迭代器删除,也可以通过pair中first删除,也可以通过迭代器区间删除。

void test_map()
{
	map<string, string> m;
	pair<string, string>kv1("left", "左");
	m.insert(kv1);
	m.insert(pair<string, string>("right", "右")); // 匿名对象构造
	m.insert(make_pair("one", "1"));
	m.insert(make_pair("two", "2"));
	m.insert(make_pair("three", "3"));
	map<string, string>::iterator it = m.find("one");


![img](https://img-blog.csdnimg.cn/img_convert/15284c2315a2e2cdc447b01a748fa0a1.png)
![img](https://img-blog.csdnimg.cn/img_convert/20d4845c138b70002808923b75e3f3ef.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

 "1"));
	m.insert(make_pair("two", "2"));
	m.insert(make_pair("three", "3"));
	map<string, string>::iterator it = m.find("one");


[外链图片转存中...(img-t1dShgn8-1715699709157)]
[外链图片转存中...(img-Nl0AwRLQ-1715699709157)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

  • 11
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 在C++中,map、unordered_mapset和unordered_set都是STL(标准模板库)中的容器。它们都用于存储一组数据,并提供了不同的功能和性能特点。 map是一个有序的关联容器,它使用红黑树实现,可以根据键值进行快速查找。map中的元素按照键值的大小进行排序,并且每个键值只能出现一次。\[1\]unordered_map是一个无序的关联容器,它使用哈希表实现,可以根据键值进行快速查找。unordered_map中的元素没有特定的顺序,并且每个键值只能出现一次。\[2\] set是一个有序的容器,它使用红黑树实现,可以存储不重复的元素。set中的元素按照值的大小进行排序,并且每个值只能出现一次。\[3\]unordered_set是一个无序的容器,它使用哈希表实现,可以存储不重复的元素。unordered_set中的元素没有特定的顺序,并且每个值只能出现一次。 在使用这些容器时,可以使用insert()函数插入元素,使用find()函数查找元素,使用erase()函数删除元素。此外,map和unordered_map还提供了count()函数来计算特定键值的出现次数。 总结来说,map和unordered_map适用于需要根据键值进行快速查找的场景,set和unordered_set适用于需要存储不重复元素的场景。具体选择哪个容器取决于你的需求和性能要求。 #### 引用[.reference_title] - *1* *3* [C++map,unordered_map,set和unordered_set的用法和区别](https://blog.csdn.net/bryant_zhang/article/details/111600209)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [初识C++之unordered_map与unordered_set](https://blog.csdn.net/Masquerena114514/article/details/129938734)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值