第11章 关联容器

1、标准库提供8个关联容器。

map关联数组;保存关键字-值对
set只保存关键字
multimap关键字可重复的map
multiset关键字可重复的set
unordered_map用哈希函数组织的map
unordered_set用哈希函数组织的set
unordered_multimap哈希组织的map;关键字可重复
unordered_multiset哈希组织的set;关键字可重复
  • 关联容器不支持顺序容器的位置相关的操作,例如push_back或push_front;原因是挂念容器中元素是根据关键字存储的,这些操作对关联容器没有意义。
  • 关联容器的迭代器都是双向的。

2、关联容器定义和初始化

C c;默认构造函数
C c1(c2)拷贝初始化
C c1 = c2拷贝初始化
C c{a,b,c…}初始值列表初始化
C c = {a,b,c…}初始值列表初始化
C c(beg,end)迭代器初始化
  • 初始化一个map时,必须提供关键字类型和值类型:{key, value}。
  • 对于有序容器,map、multimap、set和multiset,关键字类型必须定义元素比较的方法。默认情况下,标准库使用关键字类型的 < 运算符来比较两个关键字。

3、容器关键字和值的类型;key_type,mapped_type,value_type

key_type此容器关键字类型
mapped_type每个关键字关联的类型;只适用与map
value_type对于set,与key_value相同;对于map,为pair<const key_type, mapped_type>
  • 关键字决定了排序,因此不允许改变,属于const类型。
  • 一个map的value_type是一个pair,我们可以改变pair的值,但不能改变关键字成员的值。
  • set的迭代器是const,可以用一个set迭代器读取元素的值,但不能修改。

4、关联容器与算法

  • 通常不对关联容器使用泛型算法,关键字是const这一特性意味着不能将关联容器传递给修改或重排容器元素的算法,因为这类算法需要向元素写入值。
  • 关联容器可用于只读取元素的算法,但是很多这类算法都要搜索序列,由于关联容器可以通过关键字进行快速查找,因此对其使用泛型算法几乎总是个坏主意。
  • 实际编程中,如果我们真要对一个关联容器使用算法,要么是将它当作一个源序列,要么当作一个目的位置。

5、添加元素

c.insert(v)v是value_type类型的对象,args用来构造一个元素
c.emplace(args)对于map和set,只有当元素的关键字不在c中时才插入(或构造)元素。函数返回一个pair,包含一个迭代器,指向具有指定关键字的元素,以及一个指示插入是否成功的bool值。对于multimap和multiset,总会插入(或构造)给定元素,并返回一个指向新元素的迭代器
c.insert(beg,end)beg和end是迭代器,表示一个c::value_type类型值的范围,函数返回void
c.insert(initlist)插入初始值列表,函数返回void
c.insert(p,v)类似insert(v),但将迭代器p作为一个提示,指示从哪里开始搜索新元素应该存储的位置,返回一个迭代器,指向具有给定关键字的元素
c.emplace(p,args)类似emplace(v),但将迭代器p作为一个提示,指示从哪里开始搜索新元素应该存储的位置,返回一个迭代器,指向具有给定关键字的元素
  • inset(emplace)返回的值依赖于容器类型和参数,对于不包含重复关键字的容器,添加单一元素的insert(emplace)版本返回一个pair。pair的first成员是一个迭代器,指向具有给定关键字的元素,second成员是一个bool值,false表示关键字已在容器中,insert什么事情也不做;true表示关键字不存在,元素被插入容器中。

6、删除元素

c.erase(k)从c中删除每个关键字为k的元素,返回一个size_type值,指出删除的元素的数量
c.erase§从c中删除迭代器p指定的元素,返回一个指向p之后元素的迭代器
c.erase(beg,end)删除迭代器对beg,end所表示范围中的元素,返回e

7、map的下标操作

c[k]返回关键字为k的元素;如果k不在c中,添加一个关键字为k的元素,对其进行值初始化
c.at(k)访问关键字为k的元素,带参数检查;若k不在c中,抛出一个out_of_range异常
  • 不能对一个multimap、unordered_multimap进行下标操作,因为这些容器中可能有多个值与一个关键字相关联。
  • 对一个map使用下标操作,其行为与数组或vector上的下标操作很不相同,使用一个不在容器中的关键字作为下标,会添加一个具有此关键字的元素到map中。

8、访问元素

c.find(k)返回一个迭代器,指向第一个关键字为k的元素,若k不在容器中,则返回尾后迭代器
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()
  • lower_bound(k)和upper_bound(k)不适合用于无序容器。

9、无序容器

  • 新标准定义了4个无序关联容器,这些容器不是使用比较运算符来组织元素,而是使用一个哈希函数(hash function)和关键字类型的==运算符。
  • 无序容器在存储上组织为一组桶,每个桶保存零个或多个元素。无序容器使用一个哈希函数将元素映射到桶。
    无序容器管理操作
  • 默认情况下,无序容器使用关键字类型的==运算符来比较元素,它们还使用一个hash<key_type>类型的对象来生成每个元素的哈希值。
  • 标准库为内置类型(包括指针)提供了hash模板,我们可以直接定义关键字是内置类型(包括指针类型)、string还是智能指针类型的无序容器。
  • 我们不能直接定义关键字类型为自定义类类型的无序容器,不能直接使用哈希模板,而必须提供我们自己的hash模板版本。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值