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;
相关推荐
weixin_5134499612 分钟前
PCA、SVD 、 ICP 、kd-tree算法的简单整理总结
c++·人工智能·学习·算法·机器人
烟锁池塘柳026 分钟前
一文讲透 C++ / Java 中方法重载(Overload)与方法重写(Override)在调用时机等方面的区别
java·c++·面向对象
yolo_guo1 小时前
glog单行 30000 字节限制问题
c++
cccccc语言我来了2 小时前
C++轻量级消息队列服务器
java·服务器·c++
闻缺陷则喜何志丹2 小时前
【背包 组合】P7552 [COCI 2020/2021 #6] Anagramistica|普及+
c++·算法·背包·洛谷·组合
xiaoye-duck2 小时前
【C++:C++11】C++11新特性深度解析:从类新功能、Lambda表达式到包装器实战
开发语言·c++·c++11
一个行走的民2 小时前
C++ Lambda 表达式语法详解
c++
小小码农Come on2 小时前
C++访问QML控件-----QML访问C++对象属性和方法
java·开发语言·c++
Yungoal3 小时前
项目层级结构
c++
程序员-King.3 小时前
【基础分析】—— 条件变量wait(lock, 谓词)
c++·c·多线程·条件变量