STL中 set 和 multiset

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 }
View Code

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 }
View Code

在执行期指定排序准则(默认是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 }
View Code

 

posted @ 2015-10-18 17:13  roger9567  阅读(168)  评论(0编辑  收藏  举报