在看常见STL使用的时候,看到了STL中的一个Set,本来没什么好说的,但是看到了一些之前没有看见过的代码写法,所以就记了下来。
首先介绍一下Set,中文讲是不相交集合(内部没有重复的元素),以下是C++标准给的介绍
Sets are containers that store unique elements following a specific order.
相关的说明可以参照:点击打开链接
#include<set>
#include<algorithm>
#include<iostream>
#include<iterator>
#include<string.h>
using namespace std;
struct strLess{
bool operator()(const char * s1, const char * s2) const {
return strcmp(s1, s2) < 0;
}
};
struct intGreater {
bool operator()(const int i1, const int i2) {
return i1 > i2;
}
};
void printSet(set<int> s) {
copy(s.begin(), s.end(), ostream_iterator<int>(cout, ", "));
cout << endl;
}
int main(void)
{
set<int> s1; //默认constructor
int iArray[] = { 101, 32, 13, 45, 63 };
set<int> s2(iArray, iArray + 5); //range constructor, 拷贝[first, end)之间的内容
set<int, intGreater> s3(iArray, iArray + 5, intGreater()); //指定排序标准
set<int> s4(s2); //copy constructor
/*
于此同时还可以自定义比较规则,及set中的排序顺序
range (2)
template <class InputIterator>
set (InputIterator first, InputIterator last,
const key_compare& comp = key_compare(), //指定规则
const allocator_type& alloc = allocator_type());
*/
printSet(s2);
/* insert
single element (1)
pair<iterator,bool> insert (const value_type& val);
with hint (2)
iterator insert (iterator position, const value_type& val);
range (3)
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
*/
cout << "Single insert" << endl;
s2.insert(208); //直接插入
printSet(s2);
cout << "with pos" << endl;
set<int>::iterator it = s2.begin(); //根据位置插入
s2.insert(it, 109);
printSet(s2);
cout << "Range" << endl;
s1.insert(s2.begin(), s2.end()); //按范围插入
printSet(s2);
//insert插入返回的是一个pair结构,通过pair.second可以判断插入是否成功
/*查找*/
cout << "Find Result" << endl;
cout << "find 109: " << s2.count(109) << endl; //cout查找,返回数量
it = s2.find(109);
if (it != s2.end())
cout << *it << endl;
else
cout << "404" << endl;
/*删除*/
cout << "Erase 109" << endl;
s2.erase(109); //按值删除
printSet(s2);
cout << "Erase by pos" << endl;
s2.erase(s2.begin()); //按位置删除
printSet(s2);
//s2.erase(it_begin, it_end); //范围
s2.clear(); //清空
return 0;
}
只是一些基本操作,感兴趣的用两个地方,一个是用struct封装operator当成函数对象使用;另一个是通过copy函数引导流通过标准输出进行输出
1、用struct封装operator()
看了一下书上的解释,所谓的函数对象,即调用操作符的类,表现出函数的特征,即通过“对象名 + (参数列表)”的方式使用的一个类,实质上是对operator运算符的重载。通过struct使用函数重载实质上生成函数对象,此时方才可以作为参数正确的传给set的constructor
2、通过copy函数引导流通过标准输出
copy(s.begin(), s.end(), ostream_iterator<int>(cout, ", "))
就是把迭代器范围内的元素导到标准输出流进行输出
参照一下博客 点击打开链接 侵删