《C++ Primer》第五版 读书笔记
关联容器和顺序容器的不同:关联容器中的元素是按关键字来保存和访问的。顺序容器是按它们在容器中的位置来保存和访问的。
关联容器支持高效的关键字查找和访问。两个主要的关联容器:类型是map和set.
map中的元素是一些关键字-值(kay-value)对:关键字起到索引的作用,值则表示与索引相关联的数据。
set中每个元素值包含一个关键字;set支持高效的关键字查询操作——检查一个给定关键字是否在set中。
标准库提供8个关联容器
按关键字有序保存数据
|
map |
关联数组;保存关键字-值对 |
|
Set |
关键字即值,只保存关键字的容器 |
|
Multimap |
关键字可重复出现的map |
|
Multiset |
关键字可重复出现的set |
无序集合
|
Unordered_map |
用哈希函数组织的map |
|
Unordered_set |
用哈希函数组织的set |
|
Unoedered_multimap |
哈希组织的map;关键字可重复出现 |
|
Unordered_multiset |
哈希组织的set;关键字可重复出现 |
1 关联容器支持普通容器操作
(1)类型别名
|
iterator |
const_iterator |
size_type |
|
difference_type |
value_type |
reference |
|
const_reference |
|
|
(2)构造函数
|
C c |
C c1(c2) |
|
C c(b,e) |
C c{a,b,c,…} |
(3)赋值与swap
|
c1=c2 |
c1={a,b,c,…} |
|
a.swap(b) |
swap(a,b) |
(4)大小
|
c.size() |
c.max_size() |
c.empty() |
(5)添加删除元素
|
c.insert(args) |
c.emplace(inits) |
|
c.erase(args) |
c.clear() |
(6)关系运算符
==,!= 所有容器都支持
<,<=,>,>= 无序关联容器不支持
(7)获取迭代器
|
c.begin() |
c.end() |
|
c.cbegin() |
c.cend() |
(8)反向容器的额外成员
|
reverse_iterator |
const_reverse_iterator |
|
c.rbegin() |
c.rend() |
|
c.crbegin() |
c.crend() |
关联容器中的元素是根据关键字存储的,不支持顺序容器的位置相关操作,也不支持构造函数或插入操作。关联容器的迭代器都是双向的。
map的元素是pair,pair类型的标准库,定义在头文件utility中。
pair的数据成员是public的,两个成员分别命名为first和second。
2 关联容器操作
|
关联容器额外的类型别名 |
|
|
key_type |
关键字类型 |
|
mapped_type |
关键字关联的类型,仅适用于map |
|
value_type |
对于set,与key_type相同 对于map,为pair<const key_type,mapped_type> |
不能改变一个元素的关键字,因为pair的关键字部分是const的。因此通常不对关联容器使用泛型算法,关键字是const意味着不能讲关联容器传递给修改或重排容器的算法。关联容器可用于只读取元素的算法。使用关联容器定义的专用的find成员会比调用泛型find快得多。
泛型copy算法可以将元素从一个关联容器拷贝到另一个序列。
调用inserter将一个插入器绑定到一个关联容器。
关联容器insert操作
|
c.insert(v) |
c.emplace(args) |
c.insert(b,e) |
|
c.insert(i1) |
c.insert(p,v) |
c.emplace(p,args) |
insert或emplace返回的值类型依赖于容器类型和参数。
从关联容器删除元素,使用erase
map的下标操作
map和unordered_map容器提供了下标运算符和一个对应的at函数.set不支持下标操作。
|
c[k] |
返回关键字k的元素;若k不在c中,添加一个关键字为k的元素,对其值进行初始化 |
|
c.at(k) |
访问关键字为k的元素,带参数检查;若k不在c中,抛出out_of_range异常 |
map与vector和string不同,map的下标运算返回的类型与解引用map迭代器得到的类型不同。
在一个关联容器中查找元素的操作
lower_bound和upper_bound不适用于无序容器
|
c.find(k) |
返回一个迭代器,指向第一个关键字为k的元素,若k不在容器中,则返回尾后迭代器 |
|
c.count(k) |
返回关键字等于k的元素的数量。对于不允许重复关键字的容器,返回值永远是0或1 |
|
c.lower_bound(k) |
返回迭代器,指向第一个关键字不小于k的元素 |
|
c.upper_bound(k) |
返回迭代器,指向第一个关键字大于k的元素 |
|
c.equal_range(k) |
返回一个迭代器pair,表示关键字等于k的元素的范围。若k不存在,pair的两个成员均等于c.end() |
3 无序容器
新标准定义了4个无序关联容器。无序容器不是使用比较运算符来组织元素,而是使用哈希函数和关键字类型的==运算符。
如果关键字类型固有就是无序的,或者性能测试发现问题可以用哈希技术解决,就可以使用无序容器。
无序容器在存储上组织为一组桶,每个桶保存零个或多个元素。无序容器使用一个哈希函数将元素映射到桶。
无序容器的性能依赖于哈希函数的质量和桶的数量和大小。
浙公网安备 33010602011771号