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 }

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 }

时间: 2024-10-12 15:52:42

STL中 set 和 multiset的相关文章

STL中的set容器的一点总结2

http://blog.csdn.net/sunshinewave/article/details/8068326 1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作.vector封装数组,list封装了链表,map和set封装了二叉树等,在封装这些数据结构的时候,STL按照程序员的使用习惯,以成员函数方式提供的常用操作,如:插入.排序.删除.

关于STL中的map和hash_map

以下全部copy于:http://blog.chinaunix.net/uid-26548237-id-3800125.html 在网上看到有关STL中hash_map的文章,以及一些其他关于STL map和hash_map的资料,总结笔记如下:     1.STL的map底层是用红黑树实现的,查找时间复杂度是log(n):     2.STL的hash_map底层是用hash表存储的,查询时间复杂度是O(1):     3.什么时候用map,什么时候用hash_map?     这个药看具体的

STL中的set使用方法详细

1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作.vector封装数组,list封装了链表,map和set封装了二叉树等,在封装这些数据结构的时候,STL按照程序员的使用习惯,以成员函数方式提供的常用操作,如:插入.排序.删除.查找等.让用户在STL使用过程中,并不会感到陌生. 关于set,必须说明的是set关联式容器.set作为一个容器也是

C++ STL中哈希表 hash_map介绍

过map吧?map提供一个很常用的功能,那就是提供key-value的存储和查找功能.例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改: 岳不群-华山派掌门人,人称君子剑张三丰-武当掌门人,太极拳创始人东方不败-第一高手,葵花宝典... 这些信息如果保存下来并不复杂,但是找起来比较麻烦.例如我要找"张三丰"的信息,最傻的方法就是取得所有的记录,然后按照名字一个一个比较.如果要速度快,就需要把这些记录按照字母顺序排列,然后按照二分法查找.但是增加记录的时候同时需要保持记

STL中关于map和set的四个问题?

STL map和set的使用虽不复杂,但也有一些不易理解的地方,如: # 为何map和set的插入删除效率比用其他序列容器高? # 为何每次insert之后,以前保存的iterator不会失效? # 为何map和set不能像vector一样有个reserve函数来预分配数据? # 当数据元素增多时(10000到20000个比较),map和set的插入和搜索速度变化如何? 或许有得人能回答出来大概原因,但要彻底明白,还需要了解STL的底层数据结构. C++ STL 之所以得到广泛的赞誉,也被很多人

STL中的容器

STL中的容器 一. 种类: 标准STL序列容器:vector.string.deque和list. 标准STL关联容器:set.multiset.map和multimap. 非标准序列容器slist和rope.slist是一个单向链表,rope本质上是一个重型字符串 非标准关联容器hash_set.hash_multiset.hash_map和hash_multimap. 几种标准非STL容器,包括数组.bitset.valarray.stack.queue和priority_queue 值得

codeforces #296 div2 (527C) STL中set的运用

题意:在一块H*M的玻璃上每次划一刀(仅仅能水平或竖直).输出每次划开之后剩下的玻璃中面积最大的一块的面积. 做题的时候.觉得这么大的数据量,有每次查询输出,应该是数据结构的内容. 这道题能够用STL中的set容器来非常好地解决~set容器其本身就是用红黑树这样的数据结构来实现的.所以和原来的推測并不相悖.STL平时用的并不多.里面的一些函数非常生疏,熟悉一下 解题思路: 首先建立两个set型容器 ,每次分割都将分割的位置h或w插入到set中,因为set可以自己主动排序.运用两个函数lower_

STL中的Set用法(详+转)

set是STL中一种标准关联容器(vector,list,string,deque都是序列容器,而set,multiset,map,multimap是标准关联容器),它底层使用平衡的搜索树——红黑树实现,插入删除操作时仅仅需要指针操作节点即可完成,不涉及到内存移动和拷贝,所以效率比较高.set,顾名思义是“集合”的意思,在set中元素都是唯一的,而且默认情况下会对元素自动进行升序排列,支持集合的交(set_intersection),差(set_difference) 并(set_union),

(转)STL中set的用法

转载自here 1.关于set map容器是键-值对的集合,好比以人名为键的地址和电话号码.相反地,set容器只是单纯的键的集合.例如,某公司可能定义了一个名为bad_checks的set容器,用于记录曾经给本公司发空头支票的客户.当想知道一个值是否存在时,使用set容器是最适合的.除了两种例外情况,set容器支持大部分的map操作,这两种例外是:set不支持下标操作,而且也没有mapped_type类型,在set容器中,value_type不是pair类型,而是与key_type相同的类型.它