本文为本蒟蒻仅会的Set用法,求大神指教
Set,C++中的集合函数,采用红黑平衡树维护
multiset跟set差不多,但允许一个值出现多次
注意:以下代入的地址begin,end均为左闭右开区间
注意:以下代入的地址begin,end均为左闭右开区间
注意:以下代入的地址begin,end均为左闭右开区间
定义:
set<类型> 变量
可以套用,如:map<int,set<int> >a
(注意有空格)
当然也可以:set<int> a(cmd)
常见用法:
a.begin()
:返回a的所有值中最小值的地址
*a.begin()
:返回a的所有值中最小的值
a.end()
:返回a的所有值中最大值后面的地址(左闭右开)
a.count(k)
:k这个数在集合a中出现了多少次(如果a不是multiset,返回值为0/1)
a.empty()
:是否为空(等价于a.begin()==a.end()
)
a.size()
:返回元素个数(a.count(x)
之和)
a.find(k)
:返回a中k这个元素的地址(没找到返回end())
a.equal_range(k)
:返回为一个pair,first是a中第一个大于等于k的数,second是第一个大于k的数
a.lower_bound(k)
:跟int的一样用法
a.upper_bound(k)
:跟int的一样用法
a.clear()
:删除所有元素
a.insert(k)
:把k这个数插入到a中
a.erase(k)
:把k这个数从a中删除(k可以为地址)
a.erase(first,last)
:把a中地址first到last的元素全部删掉(不会判地址错误)
a.swap(b)
:把集合a与集合b交换
以上操作复杂度均为log(常数+++),除了insert(begin,end)和erase(begin,end)是O(n)的
详细用法演示
以下部分来源于这里,当然也有内容来自于网上各大博主的blog,在此表示感谢
以下程序中的n表示集合中数的个数,m为询问个数,
运行均在JZOJ的评测机上
equal_range(k)
返回值为pair,first是a中第一个大于等于k的数,second是第一个大于k的数。
#include <cstdio>
#include <cstdlib>
#include <set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n;
set<int> a;
int main()
{
int q;
scanf("%d",&n);
fo(i,1,n)scanf("%d",&q),a.insert(q);
printf("-------------\n");
pair<set<int>::const_iterator,set<int>::const_iterator> ans;
ans=a.equal_range(3);
printf("%d\n",*ans.first);
printf("%d\n",*ans.second);
return 0;
}
运行结果:
5
1 2 3 4 5
-------------
3
4
请按任意键继续. . .
lower_bound(k)和upper_bound(k)
跟普通的一样意思,返回的是地址
#include <cstdio>
#include <cstdlib>
#include <set>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n;
set<int> a;
int main()
{
int q;
scanf("%d",&n);
fo(i,1,n)scanf("%d",&q),a.insert(q);
printf("------------\n");
printf("%d\n",*a.lower_bound(3));
printf("%d\n",*a.upper_bound(3));
return 0;
}
运行结果
10
1 1 2 2 3 3 4 4 5 5
------------
3
4
请按任意键继续. . .
insert(k)
有2种用法:
a.insert(begin,end)
:把地址begin~end的全部插入到a中
a.insert(k)
:把a插入集合a中,返回值为pair<set<int>::iterator,bool>
,bool表示插入是否成功(a中是否有这个数),地址则为插入位置,而如果时multiset的话,返回值就只有set<int>::iterator
(总是会成功)