C++啃书(十一)关联容器

  关联容器支持高效的关键字查找和访问。
  两个主要的关联容器类型是mapset。map中的元素是关键字-值(key-value)对,set中的元素是关键字
  标准库提供8个关联容器:
在这里插入图片描述
  类型map和multimap定义在头文件map中;set和multiset定义在头文件set中;无序容器则定义在unordered_mapunordered_set中。

1.使用关联容器

在这里插入图片描述

2.关联容器概述

  关联容器(有序的和无序的)都支持9.2节中介绍的普通容器操作。关联容器不支持顺序容器的位置相关的操作,如push_back或push_front。关联容器也不支持构造函数或插入操作这些接受一个元素值和一个数量值的操作。
  除了与顺序容器相同的操作之外,关联容器还支持一些顺序容器不支持的操作和类型别名。
  关联容器的迭代器都是双向的。
(1)定义关联容器
  类似顺序容器,关联容器也是模板。当定义一个map时,必须既指明关键字类型又指明类型;定义一个set时,只需指明关键字类型。
  每个关联容器都定义了一个默认构造函数,它创建一个指定类型的空容器。我们也可以将关联容器初始化为另一个同类型容器的拷贝,或是从一个值范围来初始化关联容器,只要这些值可以转化为容器所需类型就可以。
  对于map,我们将每个关键字-值对包围在花括号中:{ key,value }。
在这里插入图片描述

  • 初始化multimap或multiset

(2)关键字类型的要求
  对于有序容器map、multimap、set和multiset,关键字类型必须定义元素比较的方法。默认情况下,标准库使用关键字类型的<运算符来比较两个关键字。

  • 有序容器的关键字类型
    在这里插入图片描述

  • 使用关键字类型的比较函数
    有序容器在定义其关键字时,其关键字的类型必须包含元素比较的方法,如果是一个类类型,且没有包含比较方法,则不合法,可以自行定义比较类型。

(3)pair类型
  pair是一种标准库类型,定义在头文件utility中。
  一个pair保存两个数据成员。类似容器,pair是一个用来生成特定类型的模板。当创建一个pair时,必须提供两个类型名,pair的数据成员将具有对应的类型。两个类型不要求一样。
  pair的默认构造函数对数据成员进行值初始化。也可以为每个成员提供初始化器:
在这里插入图片描述
  与其他标准库类型不同,pair的数据成员是public的。两个成员分别命名为first和second。我们可以用普通的成员访问符号(点运算符)来访问它们。
在这里插入图片描述

  • 创建pair对象的函数

3.关联容器操作

  除了表9.2中列出的类型,关联容器还定义了表11.3中列出的类型。这些类型表示容器的关键字和值的类型。
在这里插入图片描述
  与顺序容器一样,我们使用作用域运算符来提取一个类型的成员:
在这里插入图片描述
不能改变一个元素的关键字,因此pair的关键字部分是const的。

(1)关联容器迭代器
  当解引用一个关联容器迭代器时,我们会得到一个类型为容器的value_type的值引用。

  • set的迭代器是const的
    虽然set类型同时定义了iterator和const_iterator类型,但两种类型都只允许只读访问set中的元素。与不能改变一个map元素的关键字一样,一个set中的关键字也是const的。可以用一个set迭代器来读取元素的值,但不能修改。

  • 遍历关联容器
    map和set类型都支持表9.2中的begin和end操作,我们可以用这些函数获取迭代器,然后用迭代器来遍历容器。
    在这里插入图片描述

  • 关联容器和算法
    我们通常不对关联容器使用泛型算法。关键字是const这一特性意味着不能将关联容器传递给修改或重排容器元素的算法。
    关联容器可用于只读元素的算法。但是,很多这类算法都要搜索序列。关联容器定义了一个名为find的成员,它通过一个给定的关键字直接获取元素。使用关联容器定义的专用find成员会比调用泛型find快得多。
    在实际编程中,如果我们真要对一个关联容器使用算法,要么是将它当作一个源序列,要么当作一个目的位置。

(2)添加元素——insert
在这里插入图片描述

  • 向map添加元素
    对一个map进行insert操作时,必须记住元素类型是pair。
    在这里插入图片描述

  • 检测insert的返回值
    insert(或emplace)返回的值依赖于容器类型和参数。对于不包含重复关键字的容器,添加单一元素的insert和emplace版本返回一个pair,告诉我们插入操作是否成功。pair的first成员是一个迭代器,指向具有给定关键字的元素;second成员是一个bool值,指出元素是插入成功(true)还是已经存在于容器中(false)。

  • 展开递增语句

  • 向multiset或mutimap添加元素
    对允许重复关键字的容器,接受单个元素的insert操作返回一个指向新元素的迭代器,无须返回bool值。

(3)删除元素——erase
在这里插入图片描述

(4)map的下标操作
  map和unordered_map容器提供了下标运算符和一个对应的at函数;
  set类型不支持下标;
  multimap和unordered_multimap不能进行下标操作。

  与其他下标运算符不同的是,如果关键字不在map中,会为它创建一个元素并插入到map中,关联值将进行值初始化。由于下标运算符可能插入一个新元素,我们只可对非const的map使用下标操作。
在这里插入图片描述

  • 使用下标操作的返回值
    通常情况下,解引用一个迭代器所返回的类型与下标运算符返回的类型是一样的。但对于map,下标操作返回的是mapped_type对象,解引用得到的是value_type对象。

(5)访问元素
在这里插入图片描述

  • 对map使用find代替下标操作
    当我们只想知道一个给定关键字是否在map中,而不想改变map,应该使用find

  • 在multimap或multiset中查找元素
    find
    count

  • 一种不同的,面向迭代器的解决方法
    在这里插入图片描述

  • equal_range函数
    在这里插入图片描述

(6)一个单词转换的map
 

4.无序容器

  4个无序关联容器。这些容器不使用比较运算符来组织元素,而是使用一个哈希函数和关键字类型的**==运算符**。

  • 使用无序元素
    除了哈希管理操作之外,无序容器还提供了与有序容器相同的操作(find、insert等)。区别仅是没有排序。

  • 管理桶
    在这里插入图片描述
    无序容器容器提供了一组管理桶的函数,这些成员函数允许我们查询容器的状态以及在必要时强制容器进行重组。
    在这里插入图片描述

  • 无序容器对关键字类型的要求
    默认情况下,无序容器使用关键字类型的==运算符来比较元素,它们还使用一个hash<key_type>类型的对象来生成每个元素的哈希值。
    标准库为内置类型提供了hash模板,我们可以直接定义关键字是内置类型(包括指针类型)string智能指针类型的无序容器。
    但是,我们不能直接定义关键字类型为自定义类类型的无序容器,而是必须提供我们自己的hash模板版本。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值