十一章、关联容器
一、概述
1、关联容器中的元素是按关键字来保存和访问的;顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的
2、关联容器:map和set
- map:元素是:关键字-值的对
- set:每个元素只包含一个关键字
- multimap:关键字可重复出现的map
- multiset:关键字可重复出现的set
- unordered_map:用哈希函数组织的map
- unordered_set:用哈希函数组织的set
- unordered_multimap:关键字可重复出现的,用哈希函数组织的map
- unordered_multiset:关键字可重复出现的,用哈希函数组织的set
3、关联容器不支持顺序容器的位置相关的操作,如push_front或push_back,因为关联容器中元素是根据关键字存储的
4、关联容器的迭代器都是双向的
5、有序容器——map、multimap、set以及multiset:默认情况下,标准库使用关键字类型的<运算符来比较两个关键字,通过关键字来存储
- 在实际编程中,如果一个类型定义了“行为正常”的<运算符,则可以把它作为关键字的类型
6、无序容器——unordered_map和unordered_set:默认情况下使用关键字类型的==运算符来比较元素
- 如果关键字类型固有就是无序的,或者性能测试发现问题可以用哈希技术解决,就适合适用无序容器
二、map和set类型
1、map的元素为pair类型,定义在头文件utility中
- pair的数据成员是public的,两个成员分别命名为first和second
2、当解引用一个关联容器迭代器时,得到一个类型为容器的value_type的值的引用
- map的value_type为一个pair,可以改变pair的值,但是不能改变关键字成员的值(为const型)
- value_type的一个值为关键字,类型为key_type;第二个为值,类型为mapped_type
- set的value_type = key_type为关键字,也是const型,不可改变
3、通常不对关联容器使用泛型算法;最多在拷贝时使用copy
三、map和set的操作
1、添加:使用insert
- map使用insert(或emplace)插入单一元素的返回值:返回一一个pair,第一个元素first为一个迭代器,指向给定关键字的元素;second成员是一个bool值,指出元素插入是否成功
- multimap使用insert返回值:返回一个指向新元素的迭代器。
- 因为multimap肯定插入,所以无需返回一个bool值
- multimap:比如想建立作者到他所著书籍题目的映射
2、删除:使用erase
- c.erase(k):从c中删除关键字为k的元素,返回size_type值,指出删除元素的数量
- 如果是map则second的值为0或1;
- 如果是multimap则second为关键字的个数;
- c.erase(p):从c中删除迭代器p指定的元素,返回一个指向p之后的元素的迭代器(必须保证p指向c中一个真实元素)
3、map的下标操作
- c[k]:返回关键字为k的元素;在k不在c中时,添加一个关键字为k的元素,对其进行值初始化
- 下标操作得到一个mapped_type对象;但当解引用一个map迭代器时,得到一个value_type对象
- map的下标运算符返回一个左值,可读可写
- c.at(k):访问关键字为k的元素;若k不在c中,抛出一个out_of_range异常
4、访问元素:find、count
- c.find(k):返回一个迭代器,指向第一个关键字为k的元素,若k不在容器中,返回尾后迭代器:关键字为pair类型
- c.count(k):返回关键字等于k的元素的数量
下面三个不适用无序容器;在multi的容器时适用
- c.lower_bound(k):返回一个迭代器,指向第一个关键字不小于k的元素
- c.upper_bound(k):返回一个迭代器,指向第一个关键字大于k的元素
- c.equal_bound(k):返回一个迭代器pair,表示关键字k的元素的范围;如果k不存在两个元素都为c.end(); first = c.lower_bound(k);second = c.upper_bound(k)