在看常见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, ", "))
就是把迭代器范围内的元素导到标准输出流进行输出
参照一下博客 点击打开链接 侵删