c++关联容器
介绍
关联容器支持高效的关键字查找和访问。两个主要的关联容器类型是map和set。
map中的元素是关键字-值对:关键字起到索引的作用,值则表示与索引相关联的数据。
set中每个元素只包含一个关键字;set支持高效的关键字查找。
map与multimap定义在头文件map中;set与multiset定义在头文件set中;无序容器则定义在头文件unordered_map和unordered_set中。
容器名 | 介绍 |
---|---|
有序集合 | |
map | 关联数组,保存键值对 |
set | 关联字即值,即只保存关键字的容器 |
multimap | 关键字可重复出现的map |
multiset | 关键字可重复出现的set |
无序集合 | |
unordered_map | 用哈希组织的map |
unordered_set | 用哈希组织的set |
unordered_multimap | 用哈希组织的map,关键字可重复出现的map |
unordered_multiset | 用哈希组织的set,关键字可重复出现的set |
操作
所有关联容器都支持普通容器的常用操作。但不支持顺序容器的位置相关操作。关联容器还支持一些顺序容器不支持的操作。
定义
当定义一个map时必须声明其关键字与值的数据类型,而定义set时只需要声明关键字的类型。
当初始化一个map时必须提供关键字与值的数据类型。每个键值对包括在{}中。如下:
1 | map<T1,T2> map = { {key1,value1} ,{key2,value2}, |
关联容器对关键字有一定的要求,默认情况下其须支持’<’运算符。
pair类型
map的基础元素是pair。pair类型保存两个数据成员,类似容器。
其定义在头文件utility中。
以下是其操作:
操作 | 含义 |
---|---|
pair<T1,T2> p | T1与T2进行了值初始化。 |
pair<T1,T2> p(v1,v2) | p是一个成员类型为T1和T2的pair,分别用v1于v2进行了初始化。 |
pair<T1,T2> p={v1,v2} | 与上条等价 |
make_pair(v1,v2) | 返回一个使用v1与v2初始化的pair,其类型根据v1与v2推断。 |
p.first | 返回p的名为first的公有数据成员。 |
p.second | 返回p的名为second的公有数据成员。 |
p1 erlop p2 | 关系运算符(<,>,<=,>=)按字典顺序定义。 |
p1 == p2 | 当其两个成员变量都相等时相等。 |
p1 != p2 | 利用p1 == p2实现 |
关联容器操作
关联容器除了容器通用的类型,还定义了以下类型。
操作 | 含义 |
---|---|
key_type | 此容器类型的关键字类型 |
mapped_type | 每个关键字关联的类型,只适用于map |
value_type | 对于set与key_type相同,对于map则为pair<const key_type,mapped_type> |
迭代器
当解引用一个关联容器的迭代器时,会得到一个类型为该容器的value_type的值的引用。
对map而言其value_type是一个pair,其first保存const的关键字,second成员保存值。
set虽然有两个版本的迭代器,但都是const的。
因为关联容器的迭代器中含有const的成员,所以无法使用修改或重排算法。泛型算法中的find效率不如其自带的find。
如果要对其使用算法可以使用copy算法将其复制到另一个序列中。
增删元素
对map进行insert操作时,必须记住元素类型是pair
insert(emplace)返回的值依赖于容器类型和参数。对于不包含重复关键字的容器,添加单一元素的版本返回一个pair,其first指向具有给定关键字的元素(pair类型),其second成员是bool,若关键字已经在容器中insert(emplace)将什么都不会做且bool为false,若关键字不在,则元素被插入且bool为true。
操作 | 含义 |
---|---|
c.insert(v)/c.emplase(args) | v为value_type类型的对象,args用来构造一个元素,当元素关键字不能插入,返回pair,其中包含一个迭代器,指向具有指定关键字的元素,以及一个指示插入是否成功的bool |
c.insert(b,e)/c.insert(il) | b和e为迭代器,表plem一个value_type类型的范围,il为这种值的花括号列表,返回void |
c.insert(p,v)/c.emplace(p,args) | 将迭代器·p作为一个提示,指示从哪里开始搜索新元素应该存储的位置,返回迭代器,指向具有给定关键字的元素 |
c.erase(k) | 从c中删除每个关键字为k的元素,返回删除数据数量 |
c.erase(p) | 从c中删除p指定的元素,p必须指向一个填充元素,返回一个指向p之后元素的迭代器,若p指向尾元素,则返回c.end() |
c.erase(b,e) | 删除迭代器b和e所表范围中的元素,返回e |
map下标操作
map与unordred_map容器提供了下标运算符与对应的at函数。
而set不支持下标运算。
操作 | 含义 |
---|---|
c[k] | 返回关键字为k的元素;若k不在则添加一个k并进行值初始化。 |
c.at(k) | 返回关键字为k的元素;若k不在则抛出out_of_range的异常 |
访问元素
操作 | 含义 |
---|---|
c.find(k) | 返回一个迭代器,指向第一个关键字为k的元素,若k不在容器中,则返回尾后迭代器 |
c.count(k) | 返回关键字为k的个数 |
c.lower_bound(k) | 返回一个迭代器,指向第一个关键字不小于k的元素 |
c.upper_bound(k) | 返回一个迭代器,指向第一个关键字大于k的元素 |
c.equal_range(k) | 返回一个迭代器pair,表关键字k的元素范围,若k不存在则两个成员都为c.end() |
参考资料
C++primer中文版(第五版) 电子工业出版社。