C++ Primer(顺序容器 上)
第九章 顺序容器
标准库定义了三种顺序容器类型:vector、list 和 deque。
标准库还提供了三种容器适配器(adaptors): stack, queue, priority_queue
9.1顺序容器的定义:
#include <vector>
vector<string> svec;
#include <list>
list<int> ilist;
#include <deque>
deque<Sales_item> items;
9.1.1容器元素的初始化
表9-2 容器构造函数 |
|
C<T> c; |
创建一个名为c的空容器。C是容器类型名,如vector,T是元素类型,如int或string。 适用于所有容器 |
C c(c2); |
创建容器c2的副本c;c和c2必须具有相同的容器类型,并存放相同的元素。适用于所有容器 |
C c(b, e); |
创建c,其元素是迭代器b和e标示的范围内元素的副本。适用于所有容器 |
C c(n, t); |
用n个值为t的元素创建容器c,其中值t必须是容器类型C的元素类型的值,或者是可转换为该类型的值 只适用于顺序容器 |
C c(n); |
穿件有n个值初始化 (value-initialized) 元素的容器c 只适用于顺序容器 |
1.将一个容器初始化为另一个容器的副本
容器类型混合元素类型相匹配
vector<int> ivec; //定义一个空的vector<int>类型,
vector<int> ivec2(ivec); //复制初始化
vector ivec2(ivec); // 同上
vector<int> ivec(10); // 十个零
vector<int>ivec(10,1); //十个一
2.初始化为一段元素的副本
vector<int> ivec(vec.begin(),vec.end()) //用两个迭代器复制初始化
3.分配和初始化指定数目的元素
const list<int>::size_type list_size=64;
list<string> slist(list_size,"ee"); //64个字符串,每个都是ee
9.1.2 容器内元素的类型约束
容器内的元素类型必须是 1)支持赋值运算,2)支持复制
除了引用类型外,所有内置和复合类型都可以做元素类型。
容器的容器
vector< vector<int> .> lines; // attention!!!!这里> .> 之间必须有空格!!
9.2迭代器和迭代器范围
所有标准库容器都支持*iter,iter->mem,++iter,iter++,--iter,iter--,iter1==iter2,iter1!=iter2
vector和deque提供了额外的运算!!如iter+n,iter-n,iter1+=iter2,>,<,>=,<=等.
list容器的迭代器既不支持算术运算(加法或减法),也不支持关系运算(<=,<,>=,>),只提供前置或后置的自增,自减运算及相等(不等)运算。
9.2.1迭代器范围
C++ 语言使用一对迭代器标记迭代器范围(iterator range),这两个迭代器分别指向同一个容器中的两个元素或超出末端的下一位置,通常将它们命名为
first 和 last,或 beg 和 end,用于标记容器中的一段元素范围。
此类元素范围称为左闭合区间(left-inclusive interval),其标准表示方式为: [ first, last )
迭代器first和last形成一个迭代器范围需满足一下条件:它们指向同一个容器中的两个元素或超出末端的下一位置;last绝对不能位于first之前。
9.2.2使迭代器失效的容器操作
使用迭代器的时候,一定要注意那些操作可以使迭代器失效!!只要有元素的添加和删除,begin或者end的结果会失效!!最好载重新定值。
9.3顺序容器的操作
在容器中添加元素,在容器中删除元素,设置容器大小,获取容器的第一个和最后一个元素
9.3.1容器定义的类型别名
表9-5 容器定义的类型别名 |
|
size_type |
无符号整型,足以存储此容器类型的最大可能容器长度 |
iterator |
此容器类型的迭代器类型 |
const_iterator |
元素的只读迭代器类型 |
reverse_iterator |
按逆序寻址元素的迭代器 |
const_reverse_iterator |
元素的只读(不能写)逆序迭代器 |
difference_type |
足够存储两个迭代器差值的有符号整型,可为负数 |
value_type |
元素类型 |
reference |
元素的左值类型,是value_type&的同义词 |
const_reference |
元素的常量左值类型,等效于const value_type& |
9.3.2 begin和end成员
返回一个迭代器c.begin() c.end()
返回一个逆序迭代器 c.rbegin() c.rend()
容器是const,返回类型要加上const_前缀
9.3.3 在容器中添加元素
表9-7 在顺序容器中添加元素的操作 |
|
c.push_back(t) |
在容器c的尾部添加值为t的元素。返回void类型 |
c.push_front(t) |
在容器c的前端添加值为t的元素。返回void类型 只适用于list和deque容器类型 |
c.insert(p,t) |
在迭代器p所指向的元素前面插入值为t的新元素。返回指向新添加元素的迭代器。 |
c.insert(p, n, t) |
在迭代器p所指向的元素前面插入n个值为t的新元素。返回void类型 |
c.insert(p, b, e) |
在迭代器p所指向的元素前面插入由迭代器b和e标记的范围内的元素。返回void类型 |
1.在容器的指定位置添加元素
新元素的插入在迭代器指向的位置之前
list<string> lst;
list<string>::iterator iter=lst.begin();
while(cin>>word)
iter=lst.insert(iter,wrod);// 同push_front功能相同
2.不要存储end操作返回的迭代器,可以在每次做完插入运算后重新计算end迭代器值:
while(first!=v.end()){
first=v.insert(first,42);
++first;
}
9.3.4关系操作符
两个容器可以大小比较,其实是其元素在作比较,如果元素不支持,则容器也不支持
ivec1 < ivec2
要求完全匹配,即容器类型与元素类型都相同,且元素类型支持<操作
9.3.5容器大小的操作
表9-8 顺序容器的大小操作 |
|
c.size() |
返回容器c中的元素个数。返回类型为c::size_type |
c.max_size() |
返回容器c可容纳的最多元素个数。返回类型为c::size_type |
c.empty() |
返回标记容器大小是否为0的布尔值 |
c.resize(n) |
调整容器c的长度大小,使其能容纳n个元素 如果n<c.size(), 则删除多出来的元素; 否则,添加采用值初始化的新元素 |
c.resize(n, t) |
调整容器c的大小,使其能容纳n个元素。所有新添加的元素之都为t |
9.3.6访问元素
表9-9 访问顺序容器内元素的操作 |
|
c.back() |
返回容器c的最后一个元素的引用。如果c为空,则该操作未定义 |
c.front() |
返回容器c的第一个元素的引用。如果c为空,则该操作未定义 |
c[n] |
返回下标为n的元素的引用 如果n<0或n>=c.size(),则该操作未定义 只适用于vector和deque容器 |
c.at(n) |
返回下表为n的元素的引用。如果下标越界,则该操作未定义 只适用于vector和deque容器 |
9.3.7删除元素
表9-10 删除顺序容器内元素的操作 |
|
c.erase(p) |
删除迭代器p所指向的元素 返回一个迭代器,它指向被删除元素后面的元素。如果p指向容器内的最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。如果p本身就是指向超出末端的下一位置的迭代器,则该函数未定义 |
c.erase(b, e) |
删除迭代器b和e所标记的范围内的所有元素 返回一个迭代器,它指向被删除元素段后面的元素。如果e本身就是指向超出末端的下一位置的迭代器,则返回的迭代器也指向容器的超出末端的下一位置 |
c.clear() |
删除容器c内的所有元素。返回void |
c.pop_back() |
删除容器c的最后一个元素。返回void。如果c为空容器,则该函数未定义 |
c.pop_front() |
删除容器c的第一个元素。返回void。如果c为空容器,则该函数未定义。只适用于list和deque容器 |
1.删除第一个或最后一个元素
vector容器类型不支持pop_front操作。
pop_front操作通常与front操作配套使用
while(!ilist.empty()){
process(ilist.front());
ilist.pop_front();
}//使用front获取要处理的元素,使用pop_front从容器list删除该元素。
2.删除一个元素
必须在容器中找到要删除的元素后,才能使用erase操作,且必须保证迭代器不是end迭代器
string searchValue("quasimodo");
list<string>::iterator iter=find(slist.begin(),slist.end(),searchValue);
if(iter!=slist.end())
slist.erase(iter);
9.3.8赋值与swap
表9-11 顺序容器的赋值操作 |
|
c1 = c2 |
删除容器c1的所有元素,然后将c2的元素复制给c1。c1和c2的类型(包括容器类型和元素类型)必须相同 |
c1.swap(c2) |
交换内容:调用完该函数后,c1中存放的是c2原来的元素,c2中存放的则是c1原来的元素。c1和c2的类型必须相同。该函数的执行速度通常要比将c2的元素复制到c1的操作快 |
c.assign(b, e) |
重新设置c的元素:将迭代器b和e标记的范围内所有的元素复制到c中。b和e必须不是指向c中元素的迭代器 |
c.assign(n, t) |
将容器c重新设置为存储n个值为t的元素 |
1.使用assign
assign首先删除容器中的所有元素,然后将其参数所指定的新元素插入到该容器中。两个容器类型相同,元素类型相同,可以使用赋值操作符(=)。
在不同(或相同)类型的容器内,元素类型不同但是相互兼容,赋值运算必须使用assign函数。
2.使用swap操作节省删除元素的成本
要交换的容器类型匹配,操作数必须是相同类型的容器,而且所存储的元素类型也必须相同。
9.4vector容器的自增长
vector提供两个成员函数:capacity和reserve。capacity操作获取容器需要分配更多的存储空间之前能够存储的元素总数,reserve操作则告诉vector容器应该预留多少个元素的存储空间。
size指的是容器当前拥有的元素个数。
9.5容器的选用
list容器可以高效的insert和erase一个元素且不需要移动任何其他元素,但不支持随机访问。
vector在除尾部的其他任何位置插入或删除操作都要移动这个元素右边的所有元素。
deque容器在两端插入和删除快,在中间操作代价高。
通常vector是随机访问的最佳选择。
C++ Primer(顺序容器 上)相关推荐
- 《C++ Primer 5th》笔记(9 / 19):顺序容器
文章目录 顺序容器概述 确定使用哪种顺序容器 容器库概览 迭代器 迭代器范围 使用左闭合范围蕴含的编程假定 容器类型成员 begin和end成员 容器定义和初始化 将一个容器初始化为另一个容器的拷贝 ...
- C++primer第九章 顺序容器 9.5 额外的string操作
除了顺序容器共同的操作之外,string类型还提供了一些额外的操作.这些操作中 的大部分要么是提供string类和C 风格字符数组之间的相互转换,要么是增加了允许我们用下标代替迭代器的版本. 标准库s ...
- 《C++ Primer中文版(第五版)》 第九章 顺序容器
<C++ Primer中文版(第五版)> 第九章 顺序容器 元素在顺序容器中的顺序与其加入容器时的位置相对应.关联容器中元素的位置由元素相关联的关键字值决定. 所有容器都共享公共的接口,不 ...
- 《C++Primer》第九章-顺序容器-学习笔记(1)-顺序容器定义与操作
<C++Primer>第九章-顺序容器-学习笔记(1) 文章目录 <C++Primer>第九章-顺序容器-学习笔记(1) 摘要 顺序容器的定义 容器元素的初始化 将一个容器初始 ...
- C++ Primer学习之(9)——顺序容器
读到了第二部分:容器和算法.这部分我也非常薄弱,简直不敢自称会C++了,好好读读这一部分. P404 顺序容器类型 vector:支持快速随机访问 list:支持快速插入/删除 deque:双端队列 ...
- C++ Primer 第九章 顺序容器
由于书籍上写的已经很经典了,故大部分用图片的形式来阐述概念,代码纯手打进行验证. 1.顺序容器类型:vector.deque.list.forword_list.array.string. 2.顺序容 ...
- C++ Primer 第9章 顺序容器 第一次学习笔记
1. 顺序容器概述 #include <vector> //可变大小数组.支持快速随机访问.在尾部之外的位置插入或删除元素可能很慢 #include <deque> //双端队 ...
- C++primer第九章 顺序容器 9.6 容器适配器
9.6容器适配器 除了顺序容器外,标准库还定义了三个顺序容器适配器:stack.queue和priority_queue 适配器(adaptor)是标准库中的一个通用概念.容器.迭代器和函数<3 ...
- C++primer第九章 顺序容器 9.3 顺序容器操作
9.3顺序容器操作 顺序容器和关联容器的不同之处在于两者组织元素的方式.这些不同之处直接关系到了元素如何存储.访问.添加以及删除.上一节介绍了所有容器都支持的操作(罗列于表9.2(第295页)).本章 ...
最新文章
- 华为提出十大数学挑战!解出一个就是年薪百万!
- 数据库分离 附加 sqlserver
- JS 计算日期天数差
- 进程外Session保存和全局文件错误捕获
- class checklist
- android内存测试方法,Android内存测试方法.doc
- C语言 main函数参数 argc,argv 用处,控制台应用程序模板2
- VCLSkin皮肤在MDI窗体下的问题
- Windows华丽变身MAC OS X
- webstorm主题
- 从魅力品质到伟大产品-卡诺模型
- matlab除水印,基于MATLAB视频处理——抖音小视频去除水印
- ARM920T的MMU
- 嵌入式开发培训怎么样,嵌入式开发培训前景如何?
- 【QT】缺少Qt5Widgetsd.dll等文件的问题
- VB实现移动鼠标产生粒子效果
- 【HTML】【消失的花木兰】花木兰:三兔蹦迪走,安能辨我是兔子?
- EA将向内政及手机游戏开辟商供应发行办事
- php 判断白天黑夜
- DeFi 入门必备:你需要了解的 DeFi 重要词语
热门文章
- 两数相乘:但是不用*号。如何不用*符号的两数相乘
- 在腾讯会议中如何让别人看不到演讲者视图,只有自己能看到?
- android混淆语法(android代码混淆工具)
- Java定义学生数学成绩_java程序设计,求代码 1.定义学生类,学生类有学号,姓名,语文成绩,数学成绩的属性和有参的构造...
- CAD新手制图,如何移动图形呢?
- 掌握R语言文件读取方法
- 今日头条招聘编辑党员优先;支付宝回应账单隐私风险;携程下架价格欺诈雪乡酒店丨价值早报
- EasyX图形库基础
- 路漫漫其修远兮,吾将上下而求索 fbprophet
- 联想A390t Root后出现系统升级的解决办法