**
C++ set和multiset容器的用法
**
Set:
Set是一种关联容器,它用于存储数据,并且能从一个数据集合中取出数据。它的每个元素的值必须唯一,而且系统会根据该值来自动将数据排序。每个元素的值不能直接被改变。
Set容器中可以做各种各样的操作和注意事项,要重点理解下面的内容
#include<cstdio>
#include<iostream>//这几个头文件是一定要打的
#include<set>
using namespace std;
int main()
{
set<int> S; //定义一个set容器(注意 set只能定义一个容器)
set<int> :: iterator it//定义一个指针,在set容器中我们用指针来定位,类似于数组a[i]中的i ,指针只能++或者--
S.clear() //清除所有元素
S.insert() //在集合中插入元素
S.begin() //返回指向第一个元素的迭代器
S.end() //返回指向最后一个元素的迭代器
S.count() //返回某个值元素的个数,虽然是个数,但是set会自动去重,所以count只能判断元素是否存在,也许吧。
S.swap() //交换两个集合变量
S.empty() //如果集合为空,返回true
S.equal_range() //返回集合中与给定值相等的上下限的两个迭代器
S.erase() //删除集合中的元素
S.find() //返回一个指向被查找到元素的迭代器
S.get_allocator() //返回集合的分配器
S.lower_bound() //返回指向大于(或等于)某值的第一个元素的迭代器
S.key_comp() //返回一个用于元素间值比较的函数
S.max_size() //返回集合能容纳的元素的最大限值
S.rbegin() //返回指向集合中最后一个元素的反向迭代器
S.rend() //返回指向集合中第一个元素的反向迭代器
S.size() //集合中元素的数目
S.upper_bound() //返回大于某个值元素的迭代器
S.value_comp() //返回一个用于比较元素间的值的函数
for(it=s.begin();it!=s.end();it++) printf("%d ",*it); //从头到尾输出集合内的值( 注意 不能用<=,>=,<,> 不过可以用指针it++或it--控制)
return 0;
}
Set例题1 明明的随机数 (正常的oj都有)
题意:
输入n个数,输出去重后的数个数,并从小到大输出
输入
第一行输入n
第二行输入n个数
输出
第一行输出k,代表去重后的数个数
第二行输出k个数,代表去重排序后的数
样例输入
10
20 40 32 67 40 20 89 300 400 15
样例输出
8
15 20 32 40 67 89 300 400
C++code:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
using namespace std;
set <int> S;
set <int> :: iterator it;
int a[11000];
int main()
{
int n,k;
scanf("%d",&n) ;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
S.clear();
for(int i=1;i<=n;i++) S.insert(a[i]);
printf("%d\n",S.size());
for(it=S.begin();it!=S.end();it++)
{
printf("%d ",*it);
}
return 0;
}
Set例题2 {A}+{B} (hdu1412)
题意:
给你两个集合,要求{A} + {B}.
注:同一个集合中不会有两个相同的元素.
输入
每组输入数据分为三行,第一行有两个数字n,m(0
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
using namespace std;
set <int> S;
set <int> :: iterator it;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
S.clear();
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
S.insert(x);
}
for(int i=1;i<=m;i++)
{
int x;
scanf("%d",&x);
S.insert(x);
}
set<int> :: iterator it1=S.end();
it1--;
//为什么要多定义一个it1,然后把他--? 因为这样可以避免行尾空格( 类似于for(i=1;i<n;i++) ),不会PE
for(it=S.begin();it!=it1;it++)
{
printf("%d ",*it);
}
printf("%d\n",*it);
}
return 0;
}
Multiset:
Multiset所有用法和set基本相同,但multiset和set不同点就是multiset不去重,set去重
Multiset例题1 set(noioj 3.7.3341)
描述
现有一整数集(允许有重复元素),初始为空。我们定义如下操作:
add x 把x加入集合
del x 把集合中所有与x相等的元素删除
ask x 对集合中元素x的情况询问
对每种操作,我们要求进行如下输出。
add 输出操作后集合中x的个数
del 输出操作前集合中x的个数
ask 先输出0或1表示x是否曾被加入集合(0表示不曾加入),再输出当前集合中x的个数,中间用空格格开。
输入
第一行是一个整数n,表示命令数。0<=n<=100000。
后面n行命令,如Description中所述。
输出
共n行,每行按要求输出。
样例输入
7
add 1
add 1
ask 1
ask 2
del 2
del 1
ask 1
样例输出
1
2
1 2
0 0
0
2
1 0
C++Code:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<set>
using namespace std;
multiset <int> S;
multiset <int> :: iterator it;
bool v[110000];
int a[110000];
int main()
{
int n;scanf("%d",&n);
memset(v,false,sizeof(v));
for(int i=1;i<=n;i++)
{
char ss[4];scanf("%s",ss);
int x;scanf("%d",&x);
if(ss[1]=='d')
{
S.insert(x);
v[x]=true;
printf("%d\n",S.count(x));
}
else if(ss[0]=='d')
{
printf("%d\n",S.count(x));
S.erase(x);
}
else
{
if(v[x]==true) printf("1 ");
else printf("0 ");
printf("%d\n",S.count(x));
}
}
return 0;
}