STL初步学习(set)

2.set

set可以看作一个集合,可以实现自动排序(升序)和去重

在许多题目中,都可以使用这个模板库,减少很多操作,例如P1923 第k小数,当然,这道题有很多奇奇怪怪的做法,分值都不同,之后会讲解

set的定义

#include<set>    //头文件 
using namespace std;  //这条必须加 
set<typename> a; //同vector一样,这里可以用不同的数据类型
set<typename> b[SIZE];  //定义set数组,有点类似vector的二维数组 
//b[0]~b[SIZE-1]都为set容器 

其实很多与vector相似的地方,其他的许多STL容器感觉也都差不多。接下来是set的遍历,和vector不一样的是,这里只能用迭代器遍历,不能使用数组下标

set<typename> name;
for(set<typename>::iterator it=name.begin();it!=name.end();it++){
	cout<<*it<<" ";
} //只能使用迭代器访问 

然后是涉及到的一些函数(都只介绍常用的);

①insert( ) insert(x),将x放入集合中,并自动去重和升序排序,时间复杂度为O(logN),N为元素个数

②find( ) find(x)返回set中对应值为x的迭代器,时间复杂度为O(logN)

③erase( ) 时间复杂度为O(1)

用法(1)erase(x)删除对应值为x的元素;用法(2),同find( )一起使用,erase(find(x)),用find找到x的迭代器,然后删除。

④同vector一样,可以使用clear( ),时间复杂度为O(N);size( ),时间复杂度为O(1)

另外,set和map都是用红黑树来实现

例题

P1932 第k小数

(一) 非常简单暴力的思路,直接用sort快排,输出,60分,超时

(二)学了set之后,因为set自动排序,就选用了set,至于找到第k个数,可以直接用迭代器初始值为a.begin( ),然后进行k次it++。结果只有20分,是因为set要去重,导致处理之后数据出错

	set<int>::iterator it = a.begin( );
	while(--k)it++;
	cout << *it;

(三)在查询了一些资料之后,发现有一个东西叫做multiset,和set的许多用法相同,但是他处理数据是不会进行去重的,只会升序排列。但是也只有60分,依然改变不了他超时的事实

	multiset<int>::iterator it = a.begin( );
	while(k--)it++;
	cout << *(it);

(四)无奈之下,通过题解,发现STL还有一个叫做nth_element的东西,nth_element(a,a+k,a+n),三个参数分别指(数组名,第k个,数组长度)当时直接给我看懵了,100分做法

	for(int i=1; i<=n; i++)
		scanf("%d",&a[i]);
	nth_element(a+1,a+k+1,a+1+n);
	printf("%d",a[k+1]);

当然还可以用二分做,但这里主要是讲set,就不阐述了,通过这道题,可以加深对set的一些理解,例如做题时的选择,是否考虑去重的问题,当然还有时间复杂度

原文地址:https://www.cnblogs.com/Poetic-Rain/p/13065113.html