C++中set和map的使用

0.首先说明一下容器的类型

1.序列式容器:数据间进行swap是不会剧烈破坏容器结构的。如:vector,list等

2.关联式容器:数据间进行swap不会剧烈破坏容器结构的。如:set,map等

1.set容器的初始化

1.模板的参数

T(应该是K)是容器存储数据的类型,compare是set的比较方式核心是中序遍历是升序还是降序,默认是升序,Alloc是内存池,暂时不管。

2.迭代器的类型是双向迭代器

set中的迭代器是不允许修改数据的。(不是const_iterator,但iterator也是不给修改的,给修改整棵树的结构就出错了)

3.比较的方式

less<K> 树的结构是左边大右边小。

greate<K> 树的结构是左边大右边小。

只用less实现大小比较的方式:

cpp 复制代码
//小于比较
less(cur->_key,key);
//大于比较
less(key,cur->_key);
//二者的顺序修改一下即可

4.初始化的方式

cpp 复制代码
int main()
{
//用的initailize_list参数的构造函数
	set<int> s1({ 1, 2, 3, 4, 5, 5 });
//此处的右边并不是initailize_list类型,但符合其构造函数的参数类型
//因此右边就用构造函数来生成临时对象,然后调用拷贝构造函数给s2赋值
//只是编译器优化成了直接调用成了构造函数
	set<int> s2 = { 1,3,4,5,6 };
//这里就是调用构造函数来生成临时对象,然后调用拷贝构造函数给s2赋值
	s2 = { 2,4,5,5 };
	return 0;
}

2.set的成员函数

1.erase和count和find成员函数

(2)中的size_type返回的是删除的元素次数

(1)和(3)处的所有迭代器在erase后都会失效。

count返回val的出现次数

能用于间接查找该数是否存在:

cpp 复制代码
	set<int> s1({1, 3, 5});
	int a = 3, b = 4;
//1即是有,0即是无
	cout << s1.count(a) << endl;
	cout << s1.count(4) << endl;

find,返回该val所在的迭代器,没有找到返回end处的迭代器。

(在multipleset中的find是用中序遍历查找的,必须是返回中序逻辑中找的第一个,中途遇到过也是无视的,选中序第一个的原因就是可以不断地++来找到其他的相同的值。)

2.lower_bound和upper_bound

lower_bound:返回大于等于val的迭代器区间

upper_bound:返回大于val的迭代器区间

例:查找一个区间的值

cpp 复制代码
int main()
{
	set<int> s1;
	for (int a = 1; a <= 10; a++)
	{
		s1.insert(a * 10);
	}
	for (auto& e : s1)
	{
		cout << e << ' ';
	}
	cout << endl;
	//找[30,50]区间
	auto e1 = s1.lower_bound(30);
	//e2是 >= 51的区间
	auto e2 = s1.upper_bound(50);
	s1.erase(e1, e2);
	for (auto& e : s1)
	{
		cout << e << ' ';
	}
	cout << endl;
	return 0;
}

查找[25,35]也是直接修改即可:

cpp 复制代码
auto e1 = s1.lower_bound(25);
auto e2 = s1.upper_bound(55);

可以发现upper_bound反而有助于闭区间的寻找。开去间反过来用即可。

lower_bound和upper_bound的本质还是logN查找,只是终止条件有所不同了。

题1:找两数组的交集

解法:用双指针分别指向一个数组,it1,it2。

二者相等就都++,不同就让小的++。但前提是二者都有序,因此二者都要放进set中(顺便去重)。

题2:带环链表

解法:设计一个set不断插入结点的地址直到遇到相同结点或遇到nullptr。

3.map的使用

首先对pair这个c++自带的类类型介绍一下:

cpp 复制代码
template<class T1,class T2>
struct pair
{
T1 first;
T2 second;
//和几个成员函数..
}

在map中被typedef pair<const K,class V> value_type了。

用途就是将key和value统筹成一个类类型成员。

使用:(注意,map不可以用pair(同模板参数)变量来初始化,但可以用insert)

make_pair:c++库中用于返回生成一个pair类型的(核心用途就是用于简化代码)

cpp 复制代码
int main()
{
	pair<int,int> a = pair<int, int>(1, 2);
	map<int, int> m;
	m.insert(pair<int, int>(8, 2));
	m.insert(make_pair(4, 9));
	return 0;
}

也支持多类型转换和initailize_list的的构造

cpp 复制代码
//调用c++11后支持的多参构造
map<int, int>s({1,2});
//调用initialize_list的构造函数
map<int, int> s1 = { {1,2},{4,5},{8,9} };

获取数据:

cpp 复制代码
map<int, int> s1 = { {1,2},{4,5},{8,9} };
auto a = s1.begin();
//map的迭代器也是经过重载的,返回的是pair成员变量
cout << (*a).first << (*a).second << endl;
//和list一样,当调用的成员是类类型时都有->重载
//照样返回的是地址,照样省略了operator->调用
cout << a->first << a->second << endl;
map<int, int> s3;
s3.insert(1, 2);
//不会修改,查找的根据只与key有关
s3.insert(1, 1);
cout << (*s3.begin()).first << (*s3.begin()).second << endl;
a->first++;//不允许修改key
a->second;//允许修改value;
相关推荐
郭涤生6 小时前
GPIO 基础复习
c++
小年糕是糕手6 小时前
【35天从0开始备战蓝桥杯 -- Day6】
开发语言·前端·网络·数据库·c++·蓝桥杯
星轨初途6 小时前
【C/C++底层修炼】拆解动态内存管理:四大动态内存函数、六大错误与柔性数组
c语言·开发语言·c++·经验分享·笔记·柔性数组
闻缺陷则喜何志丹6 小时前
【计算几何】和差化积及积化和差
c++·数学·计算几何
Trouvaille ~6 小时前
【项目篇】从零手写高并发服务器(九):HTTP协议支持——从TCP到应用层
linux·服务器·c++·tcp/ip·http·高并发·应用层
小此方6 小时前
Re:从零开始的 C++ STL篇(八)深度解构AVL树自平衡机制:平衡维护与旋转调整背后的严密逻辑
开发语言·数据结构·c++·算法·stl
2301_789015626 小时前
封装哈希表实现unordered_set/undered_map
c语言·数据结构·c++·算法·哈希算法
落羽的落羽6 小时前
【Linux系统】中断机制、用户态与内核态、虚拟地址与页表的本质
java·linux·服务器·c++·人工智能·算法·机器学习