《C++ Primer中文版》(第四版)信息汇总(三)

本部分主要是讨论“容器和算法”,具体内容包括:顺序容器、关联容器以及泛型算法。第9章深入探讨vector和其他顺序容器类型,第10章介绍关联容器,即不是顺序排列,而是按键排序的,第11章介绍泛型算法,这些算法通常作用于容器或序列中某一范围的元素。所谓泛型指的就是这些算法可以作用于不同的容器类型,而这些容器又可以容纳多种不同类型的元素。

九、顺序容器

将单一类型元素聚集起来成为容器,然后根据位置来存储和访问这些元素,这就是顺序容器,顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定,标准库定义了三种顺序容器类型:vector、list和deque(双端队列),他们的差别在于访问元素的方式,以及添加或删除元素相关操作的运行代价,标准库还提供了三种容器适配器:stack、queue、priority_queue,适配器是根据原始的容器类型所提供的操作,通过定义新的操作接口,来适应基础的容器类型。

1、顺序容器类型:容器只定义了少量的操作,大多数额外操作则由算法库提供。

vector:支持快速随机访问;list:支持快速插入/删除;deque:双端队列

2、顺序容器的定义:所有的容器类型都定义了默认构造函数,用于创建指定类型的空容器对象。默认构造函数不带参数。

3、将一个容器复制给另一个容器时,类型必须匹配,容器类型和元素类型都必须相同。

4、初始化为一段元素的副本:尽管不能直接将一种容器内的元素复制给另一个容器,但系统允许通过传递一对迭代器间接实现该功能。使用迭代器时,不要求容器类型相同,容器内的元素类型也可以不相同,只要它们相互兼容,能够将要复制的元素转化为所构建的新容器的元素类型,即可实现复制。

5、创建顺序容器时,可显式指定容器大小和一个元素初始化式,接受容器大小做形参的构造函数只适用于顺序容器,而关联容器不支持这种初始化。

6、容器的容器,注意在指定容器元素为容器类型时,必须使用空格。否则系统会认为>>是单个符号,为右移操作符。

7、常用迭代器运算

8、vector和deque容器的迭代器提供额外的运算:迭代器算术运算,以及使用除了==和!=之外的关系操作符来比较两个迭代器。

9、使用左闭合区间[first,last)的编程意义:当first与last相等时,迭代器范围为空;当first与last不相等时,迭代器范围内至少有一个元素,而且first指向该区间中的第一个元素。此外,通过若干次自增运算可以使first的值不断增大,直到first==last为止。

10、begin和end成员

c.begin():返回一个迭代器,它指向容器c的第一个元素;c.end():返回一个迭代器,它指向容器c的最后一个元素的下一位置

c.rbegin():返回一个逆序迭代器,它指向容器c的最后一个元素;c.rend():返回一个逆序迭代器,它指向容器c的第一个元素前面的位置

11、在顺序容器中添加元素:

12、避免存储end操作返回的迭代器,如下面代码,该段代码将导致死循环,问题在于这个程序将end操作返回的迭代器值存储在名为last的局部变量中,循环体中实现了元素的添加运算,添加元素会使得存储在last中的迭代器失效。

为了避免存储end迭代器,可以在每次做完插入运算后重新计算end迭代器值:

13、所有的容器类型都支持用关系操作符来实现两个容器的比较,比较的容器必须具有相同的容器类型,而且其元素类型也必须相同。

14、容器大小的操作

15、访问元素:

16、删除元素

17、赋值与swap

18、容器的capacity(容量)和size(长度)的区别:size指容器当前拥有的元素个数;而capacity则指容器在必须分配心存储空间之前可以存储的元素个数。

19、string类型的查找操作,这些操作都返回string::size_type类型的值

20、容器适配器:包括容器适配器、迭代器适配器和函数适配器。使用适配器是,必须包含相关的头文件:

十、关联容器

关联容器和顺序容器的本质区别在于:关联容器通过键存储和读取元素,而顺序容器则通过元素在容器中的位置顺序存储和访问元素,虽然关联容器的大部分行为与顺序容器相同,但其独特之处在于支持键的使用。关联容器支持通过键来高效地查找和读取元素,两个基本的关联容器类型是map和set,map的元素以键-值(key-value)对的形式组织,键用作元素在map中的索引,而值则表示所存储和读取的数据。set仅包含一个键,并有效地支持关于某个键是否存在的查询。

1、关联容器类型包括:(1) map,关联数组,元素通过键来存储和读取;(2) set,大小可变的集合,支持通过键实现的快速读取;(3) multimap,支持同一个键多次出现的map类型;(4) multiset,支持同一个键多次出现的set类型

2、一般来说,如果希望有效地存储不同值的集合,那么使用set容器比较合适,而map容器则更适用于存储每个键所关联的值的情况。

3、pair类型,该类型在utility头文件中定义

举例说明如下:

4、关联容器共享大部分但并非全部的顺序容器操作,关联容器不提供front,push_front,pop_front,back,push_back以及pop_back操作。关联容器不能通过容器大小来定义,因为这样的话就无法知道键所对应的值是什么,关联容器还可以根据键来排列元素。

5、map类型的定义:必须具备map头文件

6、实际应用中,键类型必须定义<操作符,而且该操作符应能正确的工作。至于是否支持其他的关系或相当运算,则不做要求。

7、map定义的类型

8、给map添加元素:可以用insert成员实现,或者先用下标操作符获取元素,然后给获取的元素赋值。使用下标访问map与使用下标访问数组或vector的行为截然不同,用下标访问不存在的元素将导致在map容器中添加一个新的元素,它的键即为该下标值。

9、查找并读取map中的元素

10、从map对象中删除元素

11、set类型:只是单纯的键的集合。

set容器支持大部分的map操作,两种例外包括:set不支持下标操作符,而且没有定义mapped_type类型,在set容器中,value_type不是pair类型,而是与key_type相同的类型,它们指的是set中存储的元素类型。

12、set容器的定义和使用:必须包含set头文件

与map容器一样,set容器的每个键都只能对应一个元素,以一段范围的元素初始化set对象,或在set对象中插入一组元素时,对于每个键,事实上都只添加一个元素。

13、multimap和multiset类型:允许一个键对应多个实例。multimap和multiset所支持的操作分别与map和set的操作相同,只有一个例外:multimap不支持下标运算。因为这类容器中,某个键可能对应多个值。

(1) 元素的添加和删除

(2) 与众不同的面向迭代器的解决方案

(3) equal_range函数:返回存储一对迭代器的pair对象,如果该值存在,则pair对象中的第一个迭代器指向该键关联的第一个实例,第二个迭代器指向该键关联的最后一个实例的下一个位置,如果找不到匹配的元素,则pair对象中的两个迭代器都将指向此键应该插入的位置。

十一、泛型算法

标准库容器定义的操作非常少,标准库没有给容器添加大量的功能函数,而是选择提供一组算法,这些算法大都不依赖特定的容器类型,可作用在不同类型的容器和不同类型的元素中,本章详细介绍泛型算法以及对迭代器更详尽的描述。泛型算法本来从来不执行容器操作,只是单独依赖迭代器和迭代器操作实现,算法基于迭代器及其操作实现,而并非基于容器操作。

1、使用泛型算法必须包含algorithm头文件#include<algorithm>.标准库还定义了一组泛化的算术算法,其命名习惯与泛型算法相同,使用这些算法则必须包含numberic头文件#include<numeric>。

2、用于指定累加起始值的第三个实参是必要的,因为accumulate对将要累加的元素类型一无所知。

3、find_first_of的使用:在第一段范围内查找与第二段范围中任意元素匹配的元素,然后返回一个迭代器,指向第一个匹配的元素,如果找不到匹配元素,则返回第一个范围的end迭代器。以下例子统计有多少个名字同时出现在这两个列表中。

4、写容器元素的算法,有些算法直接将数据写入到输入序列,另外一些则带有一个额外的迭代器参数指定写入目标。

(1) 写入输入序列的元素:本质上是安全的,只会写入与制定输入范围数量相同的元素。

(2) 不检查写入操作的算法:fill_n函数带有的参数包括一个迭代器、一个计数器以及一个值。注意不能对没有元素的空容器调用

fill_n函数(或者类似的算法)

(3) 确保算法有足够的元素存储输入数据的一种方法是使用插入迭代器,插入迭代器可以给基础容器添加元素的迭代器,通常用迭代器给容器元素赋值时,被赋值的是迭代器所指向的元素,而是用插入迭代器赋值时,则会在容器中添加一个新元素,其值等于赋值运算的右操作数的值。为了说明如何安全使用写容器的算法,下面使用back_inserter,必须包含iterator头文件。

5、对容器元素重新排序的算法,一个实例:统计段落中使用了多少个由6个或以上的字母组成的单词。

(1) 去除重复:

(2) 定义需要的使用函数:

(3) 排序算法,stable_sort算法保留相等元素的原始相对位置。

(4) 统计长度不小于6的单词

    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值