Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

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
2
3
4
map<T1,T2> map = { {key1,value1} ,{key2,value2},
{key3,value3},{key4,value4},{key5,value5}};

set<T> set = {key1,key2,key3,key4};

关联容器对关键字有一定的要求,默认情况下其须支持’<’运算符。

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中文版(第五版) 电子工业出版社。

评论