STL整理之set

转载请注明出处,部份内容引自李煜东《算法竞赛进阶指南》node



前置知识:    C++、C语言入门算法



Set是什么函数


Set是C++STL中提供的容器,set是数学上的集合——具备惟一性,即每一个元素只出现一次,而multiset则是可重集,二者的内部实现是一棵红黑树,它们支持的函数基本相同spa


Set的相关操做code


头文件blog

#include<set>

 

声明:排序


像这样:数学

set<类型>名称;

好比:it

set<int>s; set<vector<int> >s;        //vector中提供重载<
set<set<int> >s;    //平衡树嵌套,哈哈
multiset<double>s;

就像其余须要排序的数据类型同样,为一个结构体的set,须要重载小于号入门

struct node{ ......; }; set<node>s; bool operator <(const node &ai,const node &bi) { return ai.x>bi.x; }

 

set.size()


统计set中元素个数,函数返回一个整形变量,表示set中元素个数,时间复杂度O(1)

用法:名称.size(); eg. int num=s.size();


set.empty()


检查set是否为空,返回一个bool型变量,1表示set为空,不然为非空,时间复杂度O(1)

用法:名称.empty(); eg. if(s.empty()) cout<<"Myset is Empty."<<endl;


set.clear()


清空set,无返回值

用法:名称.clear();
eg.
s.clear();


set.count(x)


返回set或multiset中值为x的元素个数,时间复杂度为O(log n)

用法:名称.count(x) eg. if(!s.count(x)) ans++;


迭代器


双向访问迭代器,不支持随机访问,支持星号解除引用,仅支持“++”,“--”这两个算术操做
引用和操做:

set<类型>::iterator it; eg. set<int>::iterator it=s.begin(); it++; it--;


若把it++,则it将会指向“下一个”元素。这里的下一个是指在key从小到大排序的结果中,排在it下一名的元素。同理,若把it--,则it会指向排在上一个的元素

“++”,“--”操做的复杂度均为O(log n)


遍历set及访问其中的元素

//set
for(set<int>::iterator it=s.begin();it!=s.end();it++) cout<<*it<<endl;    //取出这个迭代器指向的元素 //set嵌套
for(set<set<int> >::iterator it=s.begin();it!=s.end();it++) { //首先取出set中嵌套的set
    for(set<int>::iterator rit=(*it).begin();rit!=(*it).end();rit++) cout<<*rit<<' ';    //遍历这个set
    cout<<endl; }


set.begin()


返回集合的首迭代器,即指向集合中最小元素的迭代器,时间复杂度为O(1)

用法:名称.begin(); eg. map<int>::iterator it=s.begin();


set.end()


返回集合的尾迭代器,众所周知,STL中区间都是左闭右开的,那么end()函数返回的迭代器即为指向集合中最大元素的下一个位置的迭代器,所以--s.end()才是指向集合中最大元素的迭代器,时间复杂度为O(1)

用法:名称.end(); eg. maxn=*(--s.end());        //取出最大元素


set.insert(x)


在set中插入元素,返回插入地址的迭代器和是否插入成功的bool并成的pair,时间复杂度为O(log n)

PS:set在进行插入的时候是不容许有重复的键值的,若是新插入的键值与原有的键值重复则插入无效(multiset能够重复)

用法:名称.insert(set类型); eg. s.insert(3);


set.erase(参数)


删除,参数能够是元素或者迭代器,返回下一个元素的迭代器,时间复杂度为O(log n),注意在multiset中s.erase(x)会删除全部值为x的元素

用法:名称.erase(参数); eg. set<int>::iterator it=s.begin(); s.erase(it); s.erase(3);


set.find(x)


在set中查找值为x的元素,并返回指向该元素的迭代器,若不存在,返回set.end(),时间复杂度为O(log n)

用法:名称.find(x); eg. if(s.find(x)!=s.end()) cout<<"Have Found!"<<endl;


set.lower_bound(x)/upper_bound(x)


两个神奇的东西,决定把他们放在一块谈一谈

用法与find相似,但查找的条件略有不一样,时间复杂度O(log n)

s.lower_bound(x)表示查找>=x的元素中最小的一个,并返回指向该元素的迭代器

s.upper_bound(x)表示查找>x的元素中最小的一个,并返回指向该元素的迭代器

举个例子:

在set{3,5,7,8,13,16}中

对于在set中存在的元素,好比8

s.lower_bound(8)返回8所在位置的迭代器

s.upper_bound(8)返回13所在位置的迭代器

对于在set中不存在的元素,好比12

两个函数返回的则都是13所在位置的迭代器


特殊地,


对于比set中最大的元素大的元素,好比20

两个函数返回的都是s.end()

相关文章
相关标签/搜索