微软帮助文档中对集合(set)的解释: “描述了一个控制变长元素序列的对象(注:set中的key和value是Key类型的,而map中的key和value是一个pair结构中的两个分量)的模板类,每一个元素包含了一个排序键(sort key)和一个值(value)。对这个序列可以进行查找、插入、删除序列中的任意一个元素,而完成这些操作的时间同这个序列中元素个数的对数成比例关系,并且当游标指向一个已删除的元素时,删除操作无效。”
而一个经过更正的和更加实际的定义应该是:一个集合(set)是一个容器,它其中所包含的元素的值是唯一的。这在收集一个数据的具体值的时候是有用的。集合中的元素按一定的顺序排列,并被作为集合中的实例。如果你需要一个键/值对(pair)来存储数据,map是一个更好的选择。一个集合通过一个链表来组织,在插入操作和删除操作上比向量(vector)快,但查找或添加末尾的元素时会有些慢。
函数 | 说明 |
insert | 向集合中添加一个元素 |
clear | 清空 |
empty | 判断当前容器是否为空 |
count | 计算元素在容器中的个数,对于std::set为1(存在)或者0(不存在)。可用于判断元素是否存在 |
erase | 删除指定元素 |
find | 查找指定元素 |
size | 取得当前容器内元素个数 |
max_size | 容器的最大存储元素个数 |
应用举例:
1. 插入操作
#include <set>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
set<int> aset;
aset.insert(1);
aset.insert(aset.begin(),2);
aset.insert(3);
pair<set<int>::iterator,bool> tp = aset.insert(4);
if(tp.second == true)
{
cout << "insert succeed." << endl;
}
else
{
cout << "insert failed." << endl;
}
}
2. 清空当前容器
如果当前容易中的元素是自己new出来的对象的指针,那么在调用clear函数之前,需要自己先释放掉这部分内存。比如进行如下的操作。
myclass *p1 = new myclass();
myclass *p2 = new myclass();
myclass *p3 = new myclass();
std::set<myclass *> set_class;
set_class.insert(p1);
set_class.insert(p2);
set_class.insert(p3);
set_class.clear();
如果程序只进行如上的步骤,那么p1、p2、p3其实没有别真正的释放,如果是在SVR中运行的话,会造成内存泄露。实际应该如下所示。
myclass *p1 = new myclass();
myclass *p2 = new myclass();
myclass *p3 = new myclass();
std::set<myclass *> set_class;
set_class.insert(p1);
set_class.insert(p2);
set_class.insert(p3);
for (std::set<myclass *>::iterator it = set_class.begin(); it != set_class.end(); it++)
delete *it;
set_class.clear();
对于erase操作也是如此。在删除元素之前,如有必要先自己释放内存。
3. 交集(set_intersection)、并集(set_union)、差集(set_difference)、对称差(set_symmetric_difference)
通过algorithm中提供的set_intersection、set_union、set_difference、set_symmetric_difference四个函数,可以方便的实现集合的交、并、差、对称差操作。
#include <algorithm>
#include <set>
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = {0,1,2,3,4,5,6,7,8};
int b[] = {2,4,6,8,10};
set<int> s1(a,a+9);
set<int> s2(b,b+5);
set<int>::iterator it;
set<int> sunion;
set<int> sintersection;
set<int> sdifference;
set<int> ssymmetricdiff;
std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(sintersection,sintersection.begin()));
//std::set_union(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(sunion,sunion.begin()));
//std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(sdifference,sdifference.begin()));
//std::set_symmetric_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(ssymmetricdiff,ssymmetricdiff.begin()));
for(it=sintersection.begin();it!=sintersection.end();it++)
//for(it=sunion.begin();it!=sunion.end();it++)
//for(it=sdifference.begin();it!=sdifference.end();it++)
//for(it=ssymmetricdiff.begin();it!=ssymmetricdiff.end();it++)
{
cout << *it << endl;
}
}