C++ Primer学习之(9)——顺序容器
读到了第二部分:容器和算法。这部分我也非常薄弱,简直不敢自称会C++了,好好读读这一部分。
P404
顺序容器类型
vector:支持快速随机访问
list:支持快速插入/删除
deque:双端队列
顺序容器适配器
stack:后进先出(LIFO)堆栈
queue:先进先出(FIFO)队列
priority_queue:有优先级管理的队列
为了使程序更清晰,简短,容器类型最常用的构造函数是默认构造函数。在大多数的程序中,使用默认构造函数能达到最佳运行时性能,并且使容器更容易使用。
P407:
不能直接将一个容器内的元素复制给另一个容器,但系统允许通过传递一对迭代器间接实现该功能。
迭代器标记了要复制的元素范围,这些元素用于初始化新容器的元素。采用这种初始化形式可复制不能直接复制的容器,更重要的是,可以实现复制其他容器的一个子序列:
// initialize slist with copy of each element of svec
list<string> slist(svec.begin(), svec.end());
// find midpoint in the vector
vector<string>::iterator mid = svec.begin + svec.size() / 2;
// initialize front with first half of svec:The elements up to but not including *mid
deque<string> front(svec.begin(), mid);
// initialize back with second half of svec:The elements *mid through end of svec
deque<string> back(mid, svec.end());
P409:
容器元素类型必须满足以下两个约束:
1. 元素类型必须支持赋值运算。
2. 元素类型的对象必须可以复制。
P410:
容器操作的特殊要求
如果容器存储类类型的对象,那么只有当其元素类型提供默认构造函数时,容器才能使用这种构造函数。
注意,在指定容器元素为容器类型时,必须如下使用空格:
vector<vector<string> > lines; // ok: space requiresd between close >
vector<vector<string>> lines; // error: >> treated as shift operator
必须用空格隔开相邻的>符号,否则,系统会认为>>是右移操作符,并导致编译错误。
P411:
迭代器和迭代器范围
注:这节非常适合编码的时候查阅。
P415:
C++语言使用一对迭代器标记迭代器范围(iterator range)。
last和end很容易引起误解,其实last从来都不指向元素范围的最后一个元素,而是指向最后一个元素的下一位置。该范围内的元素包括迭代器first指向的元素,以及从first开始一直到迭代器last指向的位置之前的所有元素。如果两个迭代器相等,则迭代器范围为空。
此类元素范围称为左闭合区间(left-inclusive interval)。
// to be read as:includes first and each element up to but not including last
[fist, last)
对形成迭代器范围的迭代器的要求:
1. 它们指向同一容器中的元素或超出末端的下一位置。
2. 如果这两个迭代器不相等,则对first反复做自增运算必须能够到达last。
使用左闭合区间的编程意义
程序员可以安全地编写如下的循环:
while (first != last)
{// safe to use *first because we know there is at least one element++first;
}
注:之前一直都对last指向的元素不太清楚,了然。
P418:
使用迭代器时,通常可以编写程序使得要求迭代器有效的代码范围相对较短。然后,在该范围内,严格检查每一条语句,判断是否有元素添加或删除,从而响应地调整迭代器的值。
P419:
begin和end操作产生指向容器内第一个元素和最后一个元素的下一位置的迭代器。
注:下一位置!
P420:
除了push_back运算,list和deque容器类型还提供了类似的插入新元素的操作:push_front。
关键概念:容器元素都是副本
在容器中添加元素时,系统会将元素值复制到容器里。被复制的原始值与新容器中的元素各不相关。
P422:
相较于push_back和push_front,insert提供了一组更通用的插入方法,实现在容器的任意指定位置插入新元素。有三种形式的插入新元素方式:
1. 新元素插入在迭代器指向的位置之前。
slist.insert(iter, spouse); // insert spouse just before iter
2. 第二个版本提供在指定位置插入指定数量的相同元素的功能:
svec.insert(svec.end(), 10, "Anna");
3. 实现在容器中插入由一对迭代器标记的一段范围内的元素:
string sarray[4] = {"quasi", "simba", "frollo", "scar"};
// insert all the elements in array at end of slist
slist.insert(slist.end(), sarray, sarray+4);
list<string>::iterator slist_iter = slist.begin();
// insert last two elements of sarray before slist_iter
slist.insert(slist_iter, sarray+2, sarray+4);
P423:
任何insert或push操作都可能导致迭代器失效。当编写循环将元素插入vector或deque容器中时,程序必须确保迭代器在每次循环后得到更新。
P425:
容器大小比较:
1. 如果两个容器具有相同的长度而且所有元素相等,则两容器相等;
2. 如果两个容器长度不相同,但较短容器中所有元素都等于较长容器对应元素,则较短容器小于另一个容器;
3. 如果两个容器都不是对文的初始子序列,则它们的比较结果取决于所比较的第一个不相等的元素。
注:让我想到了if..else..语句。
P429:
如果容器非空,那么容器类型的front和back成员将返回容器内第一个或最后一个元素的引用。
// check that there are elements before dereferencing an iterator
// or calling front or back
if (!ilist.empty())
{// val1 and val2 refer to the same elementlist<int>::reference val1 = *list.begin();list<int>::reference val2 = ilist.front();// last1 and last2 refer to the same elementlist<int>::reference last1 = *--ilist.end();list<int>::reference last2 = ilist.back();
}
P432:
删除一个或一段元素更通用的方法是erase操作。该操作有两个版本:删除由一个迭代器指向的单个元素,或删除由一对迭代器标记的一段元素。erase的这两种形式都返回一个迭代器,它指向被删除元素或元素段后面的元素。
通常,程序员必须在容器中找出要删除的元素后,才使用erase操作。寻找一个指定元素的最简单方法是使用标准库的find算法。
string searchValue("Quasimodo");
list<string>::iterator iter = find(slist.begin, slist.end(), searchValue);
if (iter != slist.end())
{slist.erase(iter);
}
P437:
关于swap的一个重要问题在于:该操作不会删除或插入任何元素,而且保证在常量时间内实现交换。由于容器内没有移动任何元素,因此迭代器不会失效。
P437:
如果容器中已经没有空间容纳新的元素,vector必须重新分配存储空间,用来存放原来的元素以及新添加的元素:存放在旧存储空间中的元素被复制到新存储空间里,接着插入新元素,最后撤销旧的存储空间。
capacity和reserve成员
capacity操作获取在容器需要分配更多的存储空间之前能够存储的元素总数
reserve操作则告诉vector容器应该预留多少个元素的存储空间
每当vector容器不得不分配新的存储空间时,以加倍当前容量的分配策略实现重新分配。
注:面试的时候被问过vector预留空间的问题,当时没有答上,还是基础不够牢固。
P441:
容器的选用
分配连续存储元素的内存空间会影响内存分配策略和容器对象的开销。元素是否连续存储还会显著地影响:
1. 在容器的中间位置添加或删除元素的代价。
2. 执行容器元素的随机访问的代价。
选择容器类型的法则:
1. 如果程序要求随机访问元素,则应使用vector或deque容器。
2. 如果程序必须在容器的中间位置插入或删除元素,则应采用list容器。
3. 如果程序不是在容器的中间位置,而是在容器首部或尾部插入或删除元素,则应采用deque容器。
4. 如果只需在读取输入时在容器的中间位置插入元素,然后需要随机访问元素,则可考虑在输入时将元素读入到一个list容器,接着对此容器重新排序,使其适合顺序访问,然后将排序后的list容器复制到一个vector容器。
如果无法确定某种应用应该采用哪种容器,则编写代码时尝试只使用vector和lists容器都提供的操作:使用迭代器,而不是下标,并且避免随机访问元素。
P444:
再谈string类型
string库定义了大量使用重复模式的函数。由于该类型支持的函数非常多,初次阅读本节会觉得精神疲惫。
注:关于string的这节,非常适合使用时候查阅。
P459:
标准库还提供了三种顺序容器适配器:queue,priority_queue和stack。
使用适配器时,必须包含相关的头文件:
#include <stack> // stack adaptor
#include <queue> // both queue and priority_queue adaptors
默认的stack和queue都是基于deque容器实现的,而priority_queue则在vector容器上实现。
stack栈可以建立在vector,list或者deque容器之上。而queue适配器要求其关联的基础容器必须提供push_front运算,因此只能建立在list容器上,而不能建立在vector容器上。priority_queue适配器要求提供随机访问功能,因此可建立在vector或deque容器上,但不能建立在list容器上。
标准库队列使用了先进先出(FIFO)的存储和检索策略。标准库提供了两种风格队列:FIFO队列(FIFO queue,简称queue),以及优先级队列(priority queue)。
priority queue允许用户为队列中存储的元素设置优先级。这种队列不是直接将新元素放置在队列尾部,而是放在比它优先级低的元素前面。
也许我读完C++ Primer也成为不了大牛,也没办法去自己心仪的公司,也很难涨工资,有时也会怀疑自己继续读下去的意义,毕竟技术日新月异,可是还是尽自己所能,好好学习,如果努力了还做不到,起码无悔。
第九章 顺序容器(完)
C++ Primer学习之(9)——顺序容器相关推荐
- C++ Primer 学习笔记14 顺序容器
6.访问元素 如果容器非空,那么容器类型的front和back成员将返回容器的第一个和最后一个元素的引用. [与begin和end的对比:] 1)begin和end返回容器类型的迭代器,而不是引用: ...
- 《C++Primer》第九章-顺序容器-学习笔记(1)-顺序容器定义与操作
<C++Primer>第九章-顺序容器-学习笔记(1) 文章目录 <C++Primer>第九章-顺序容器-学习笔记(1) 摘要 顺序容器的定义 容器元素的初始化 将一个容器初始 ...
- 【C++ Primer 学习笔记】: 容器和算法之【泛型算法】
本系列博客主要是在学习 C++ Primer 时的一些总结和笔记. [C++ Primer 学习笔记]: 容器和算法之[泛型算法] 本文地址:http://blog.csdn.net/shanglia ...
- C++ Primer 第9章 顺序容器 第一次学习笔记
1. 顺序容器概述 #include <vector> //可变大小数组.支持快速随机访问.在尾部之外的位置插入或删除元素可能很慢 #include <deque> //双端队 ...
- C++ primer 第9章 顺序容器
文章目录 顺序容器类型 确定使用哪种顺序容器 容器库概览 容器操作 迭代器 迭代器支持的所有操作 迭代器支持的所有运算 迭代器范围 对构成范围的迭代器的要求 标准库迭代器范围左闭右开的三种性质 容器定 ...
- C++Primer 第9章 顺序容器
写在前面 到了,看来侯捷老师的STL,我对C++的标准库是有了极大的兴趣的,本章主要讲述的是标准库中的顺序容器的使用. 顺序容器 首先什么是顺序容器呢?是将数据以一定次序存储在内存当中,其数据的顺序不 ...
- C++ primer 第9章顺序容器 思维导图
- 《C++ Primer 5th》笔记(9 / 19):顺序容器
文章目录 顺序容器概述 确定使用哪种顺序容器 容器库概览 迭代器 迭代器范围 使用左闭合范围蕴含的编程假定 容器类型成员 begin和end成员 容器定义和初始化 将一个容器初始化为另一个容器的拷贝 ...
- C++primer第九章 顺序容器 9.6 容器适配器
9.6容器适配器 除了顺序容器外,标准库还定义了三个顺序容器适配器:stack.queue和priority_queue 适配器(adaptor)是标准库中的一个通用概念.容器.迭代器和函数<3 ...
最新文章
- MinGW-notepad++开发c/c++程序
- 原创 Reflector 8.1 反激活
- jenkins安装与配置windows_Windows下Scoop安装、配置与使用
- mysql 异常笔记
- python入门基础知识实例-Python入门基础知识实例,值得收藏!
- 百望税控服务器管理系统安装,电子发票客户端安装和配置操作说明
- 2021王道考研pdf
- linux键盘输入空格失效,电脑键盘空格键失灵不能用如何修复
- C# dataGridView限制某一行的单元格只输入数字的方法之一
- 【ionic框架bug】slidebox在使用model或popover后width变为0的解决方案
- Footprint:一夜暴涨250%的Boba,能否成为下个Layer 2代表
- shell 命令笔记(Linux系统常见命令和Git使用,正在更新中)
- 09_Filter过滤器(访问所有资源前,首先执行自定义过滤器类的doFilter方法)_Listener监听器(监听域对象的改变)
- 怎么样将Excel数据中的小数提取出来
- 高效记忆/形象记忆(10)英语单词记忆-音标法
- 庆祝自己喜提ROG冰刃3新锐!
- Flink学习1——运行时架构(standalone模式)
- 第十七届全国大学智能车竞赛百度智慧交通组获奖名单
- Redis数据结构Hash应用场景-存储商品、购物车、淘宝短链接、分布式Session、用户注册、发微博功能
- 伺服驱动器在机器人上的研究与应用