1. 所在头文件: <set>, 命名空间: std ; 声明如下:
1 namespace std{ 2 template <class T, 3 class Compare = less<T>, 4 class Allocator = allocator<T> > 5 class set; 6 template <class T, 7 class Compare = less<T>, 8 class Allocator = allocator<T> > 9 class multiset; 10 }
- 只要是assignable+copyable+comparable的类型T都可以作为它们的参数.
- 内部是用红黑树实现的.
- set不允许重复元素, 而multiset允许, 它们都不提供用来直接存取元素的任何操作函数.
- 通过迭代器进行元素间接存取, 有一个限制: 从迭代器角度看, 元素值是常数.
2. 基本操作
- set 和 multiset的构造/析构形式(6种):
1 set c; 2 set c(op); // op指定排序规则 3 set c1(c2); 4 set c(begin,end); 5 set c(begin,end,op) 6 c.~set()
- size()/empty()/max_size()/c1!=c2//c1==c2//c1<c2//c1>c2//c1<=c2//c1>=c2
- 要求有相同的排序准则. 不然会编译错误, 因为不是相同的类型.
- set和multiset的查询操作函数(是算法函数的特殊版本, 针对集合进行优化, 可以有对数而非线性效率)
- count(elem); //返回值为elem的元素个数
- find(elem); //返回元素值为elem的第一个元素位置, 否则返回end()
- lower_bound(elem); //返回elem的第一个可插入的位置, 也就是 元素值 >= elem元素值的第一个元素位置.
- upper_bound(elem); //和lower_bound()相对
- equal_range(elem);//返回的是pair值对
- 元素的插入和删除
- c.erase(elem/pos/[begin,end]);
- c.insert(elem/[pos,elem]/[begin,end]);
- c.clear();
- 如果multiset内含有重复元素, 就不能使用 erase()来删除第一个. 一般是用成员函数find()找到一个, 然后erase()
3. 实例:
set:
1 #include <iostream> 2 #include <iterator> 3 #include <set> 4 using namespace std; 5 int main(){ 6 typedef set<int,greater<int> > IntSet; 7 IntSet coll1; 8 coll1.insert(4); 9 coll1.insert(3); 10 coll1.insert(5); 11 coll1.insert(1); 12 coll1.insert(6); 13 coll1.insert(2); 14 coll1.insert(5); 15 16 copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," ")); 17 cout<<endl; 18 19 pair<IntSet::iterator,bool> status = coll1.insert(4); 20 if(status.second){ 21 cout<<"4 is inserted"<<endl<<distance(coll1.begin(),status.first)+1<<endl; 22 }else{ 23 cout<<"4 is already existed!"<<endl; 24 coll1.insert(7); 25 } 26 27 copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," ")); 28 cout<<endl; 29 30 set<int> coll2(coll1.begin(),coll1.end()); 31 copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," ")); 32 cout<<endl; 33 34 coll2.erase(coll2.begin(),coll2.find(3)); 35 36 copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," ")); 37 cout<<endl; 38 39 cout<<coll2.erase(5)<<" elem of 5 is removed!"<<endl; 40 41 copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," ")); 42 cout<<endl; 43 44 45 return 0; 46 }
multiset:
1 #include <iostream> 2 #include <iterator> 3 #include <set> 4 using namespace std; 5 int main(){ 6 typedef multiset<int,greater<int> > IntSet; 7 IntSet coll1; 8 coll1.insert(4); 9 coll1.insert(3); 10 coll1.insert(5); 11 coll1.insert(1); 12 coll1.insert(6); 13 coll1.insert(2); 14 coll1.insert(5); 15 16 copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," ")); 17 cout<<endl; 18 19 // 这里运行重复值, 所以没有返回失败状态. 20 IntSet::iterator pos = coll1.insert(4); 21 if(pos!=coll1.end()){ 22 cout<<"4 is inserted"<<endl<<distance(coll1.begin(),pos)+1<<endl; 23 }else{ 24 cout<<"4 is can‘t be insert!"<<endl; 25 coll1.insert(7); 26 } 27 28 copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," ")); 29 cout<<endl; 30 31 multiset<int> coll2(coll1.begin(),coll1.end()); 32 copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," ")); 33 cout<<endl; 34 35 coll2.erase(coll2.begin(),coll2.find(3)); 36 37 copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," ")); 38 cout<<endl; 39 40 cout<<coll2.erase(5)<<" elem of 5 is removed!"<<endl; 41 42 copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," ")); 43 cout<<endl; 44 45 return 0; 46 }
在执行期指定排序准则(默认是less<T>())
1 #include <iostream> 2 #include <iterator> 3 #include <set> 4 using namespace std; 5 template <class T> 6 class RuntimeCmp{ 7 public: 8 enum cmp_mode {normal, reverse}; 9 private: 10 cmp_mode mode; //在同一个类中定义了枚举, 然后定义变量. 11 public: 12 RuntimeCmp(cmp_mode m=normal): mode(m){} 13 bool operator()(const T& t1, const T& t2) const{ 14 return mode == normal? t1<t2: t1>t2; 15 } 16 // 返回值给谁用? 17 bool operator == (const RuntimeCmp& rc){ 18 return mode == rc.mode; 19 } 20 }; 21 typedef set<int,RuntimeCmp<int> > IntSet; 22 void fill(IntSet & set){ 23 set.insert(4); 24 set.insert(7); 25 set.insert(5); 26 set.insert(1); 27 set.insert(6); 28 set.insert(2); 29 set.insert(5); 30 } 31 int main(){ 32 IntSet coll1; 33 fill(coll1); 34 copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," ")); 35 cout<<endl; 36 RuntimeCmp<int> reverse_order(RuntimeCmp<int>::reverse); 37 IntSet coll2(reverse_order); 38 fill(coll2); 39 copy(coll2.begin(),coll2.end(),ostream_iterator<int>(cout," ")); 40 cout<<endl; 41 coll1 = coll2; 42 coll1.insert(3); 43 copy(coll1.begin(),coll1.end(),ostream_iterator<int>(cout," ")); 44 cout<<endl; 45 //比较排序准则是否一致, 由于coll1 从coll2 拷贝而来, 所以一致. 46 cout<<(coll1.value_comp() == coll2.value_comp())<<endl; 47 48 return 0; 49 }