C++系统学习之九:顺序容器
元素在顺序容器中的顺序与其加入容器时的位置相对应。关联容器中元素的位置由元素相关联的关键字值决定。所有容器类都共享公共的接口,不同容器按不同方式对其进行扩展。
一个容器就是一些特定类型对象的集合。顺序容器为程序员提供了控制元素存储和访问顺序的能力。
1. 顺序容器概述
容器的两种性能:
- 向容器中添加或删除元素的代价
- 非顺序访问容器中元素的代价
顺序容器类型:
如何确定使用哪种顺序容器
NOTE:通常情况下,使用vector是最好的选择。根据使用的需求对容器的哪种性能更加看重来选择合适的容器。
2. 容器库概览
容器类型上的操作有三个层次:
- 某些操作是所有容器类型都提供的
- 另外一些操作仅针对顺序容器、关联容器或无序容器
- 还有一些操作只适用于一小部分容器
每个容器都定义在一个头文件中,文件名与类型名相同。容器均定义为模板类。
以下容器操作是所有容器类型所共有的操作
2.1 迭代器
迭代器范围
一个迭代器范围由一对迭代器表示,begin指向容器的首元素,end指向容器的尾元素之后的位置。
迭代器范围是一个左闭合区间,[begin, end)。
begin可以和end指向同一个位置,但是end不能指向begin之前的位置。
2.2 容器类型成员
处理迭代器之外还有反向迭代器,对反向迭代器进行++操作,会得到上一个元素。
通过value_type得到元素类型,通过reference或const_reference得到元素类型的一个引用。
2.3 标准库array具有固定大小
与内置数组一样,array的大小也是类型的一部分。定义array时,除了指定元素类型,还要指定容器大小。
array<int, 42> arr;
其构造函数和数组差不多,列表初始化时,列表元素不要超过array的大小,可以少,array剩下的元素就进行值初始化。
array<int, 10> a={1,2,3};
剩下的7个元素值初始化为0;
此外还可以对array进行拷贝或对象赋值操作,但内置数组是不支持的
int a1[3]={0,1,2};
int a2[3]=a1; //错误
array<int, 3> a3={0,1,2};
array<int, 3> a4=a3; //正确
拷贝或赋值要保证类型相同。
2.4 赋值和swap
注意array在初始化的时候可以进行列表初始化,但是赋值的时候不能将一个花括号列表赋值给它。
NOTE:array赋值的时候,两边的运算对象必须具有相同的类型。
array<int, 3> a1 = { 0, 1, 2 };
array<int, 3> a2 = { 0 };
array<int, 3> a3 = { 2, 3, 4 };
a1 = a2;
a3 = { 0 }; //错误
对a3赋值的时候,a3的类型是array<int,3>,而右边是先把{0}转换成临时变量array<int,1> tmp,然后再将tmp赋值给a3,这是tmp和a3类型不一致。
由于可能因为大小不一致导致类型不一致,array不支持容器的赋值运算assign。
NOTE:assign操作仅适合顺序容器
赋值运算符要求左右两边的运算对象具有相同的类型,将右边运算对象所有元素拷贝到左边运算对象中。
swap
swap交换两个相同类型容器的内容。swap操作并不会交换元素本身,知识交换两个容器的内部数据结构(除array外)。这就意味着,指向容器的迭代器、引用和指针在swap操作之后都不会失效,仍指向swap操作之前的那些元素,只是这些元素属于不同容器了。
swap两个array会真正交换他们的元素。
有两个版本的swap:成员函数版本以及非成员版本,统一使用非成员版本的swap。
2.5 容器大小操作
- size:forward_list不支持size
- empty
- max_size
2.6 关系运算符
每个容器类型都支持相等运算符(=和!=),除了无序容器外都支持关系运算符。关系运算符两边的运算对象必须是相同类型的容器,且必须保存相同类型的元素。
关系比较规则:
对元素进行逐对比较。大小相同、对应元素相等则相等;元素相等,大小不等,小的小于大的;都不相等,则比较第一个不相等的元素。
NOTE:只有当容器的元素定义了相应的比较运算符操作时,才可以使用关系运算符。
3. 顺序容器操作
顺序容器和关联容器的不同之处在于两者组织元素的方式。这些不同之处直接关系到了元素如何存储、访问、添加以及删除。接下来的操作都是顺序容器所独有的操作。
3.1 向顺序容器中添加元素
新标准引入了三个新成员:emplace_front 、emplace和emplace_back,这些操作构造而不是拷贝元素。
当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中。而当我们调用emplace成员函数时,则是将参数传递给元素类型的构造函数。
empalce函数的参数根据元素类型而变化,参数必须与元素类型的构造函数相匹配。
c.empalce("978-001",25,15.99); //用三个参数直接构造对象
c.push_back("978-001",25,15.99); //错误,没有接受三个参数的push_back版本
c.push_back(Sales_data("978-001",25,15.99)); //正确
NOTE:emplace函数在容器中直接构造元素,而push_back则是创建临时对象。
3.2 访问元素
访问成员函数返回的是引用
front、back、下标和at,其返回的都是引用。
如果我们使用auto变量来保存这些函数的返回值,并且希望使用此变量来改变元素的值,必须记得将变量定义为引用类型。
auto &v=c.back(); //获得指向最后一个元素的引用
auto v=c.back(); //v不是一个引用,是c.back()的一个拷贝
下标操作必须保证在范围内操作
3.3 删除元素
3.4 特殊的forward_list操作
forward_list并未定义insert、emplace和erase,而是定义了名为insert_after、emplace_after和erase_after的操作。
3.5 改变容器大小
list<int> ls(10,45); //10个int,都是45
ls.resize(15); //将5个值为0的元素添加到ls的末尾
ls.resize(25,-1); //将10个值为-1的元素添加到ls的末尾
ls.resize(5); //从ls末尾删除20个元素
3.6 容器操作可能使迭代器失效
由于向迭代器添加元素和从迭代器删除元素的代码可能会使迭代器失效,因此必须保证每次改变容器的操作之后都正确地重新定位迭代器。
4. vector对象是如何增长的
每次都比实际所需空间多分配点空间,而不是每次都把所有元素移动到新空间。
管理容量的成员函数
capacity和size
size是指已经保存的元素的数目;而capacity则是在不分配新的内存空间的前提下它最多可以保存多少元素。
NOTE:只有当迫不得已时才可以分配新的内存空间。
5. 额外的string操作
5.1 构造string的其他方法
string定义的这些额外操作要么是提供string类和C风格字符数组之间的相互转换,要么是增加了允许我们用下标代替迭代器的版本。
substr操作
substr返回一个string,它是原始string的一部分或全部的拷贝,可以传递给substr一个可选的开始位置和计数值。
5.2 改变string的其他方法
string类型支持顺序容器的赋值运算符以及assign、insert和erase操作。除此之外,还定义了额外的insert和erase版本。
s.insert(s.size(),5,'!'); //在s末尾插入5个感叹号
s.erase(s.size()-5,5); //从s删除最后5个字符 const char *cp="Stately, plump Buck";
s.assign(cp,7); //s=="Stately"
s.insrt(s.size(),cp+7); //s=="Stately, plump Buck" string s="some string", s2="some other string";
s.insert(0,s2); //在s中位置0之前插入s2的拷贝
s.insert(0,s2,0,s2.size());
5.3 string搜索操作
搜索是大小写敏感的
逆向搜索
rfind成员函数搜索最后一个匹配,即子字符串最靠右的出现位置。
5.4 compare函数
5.5 数值转换
6. 容器适配器
除了顺序容器外,标准库还定义了三个顺序容器适配器:stack、queue和priority_queue。容器、迭代器和函数都有适配器。
本质上,一个适配器是一种机制,能使某种事物的行为看起来像另一种事物一样。
一个容器适配器接受一种已有的容器类型,使其行为看起来像一种不同的类型。
C++系统学习之九:顺序容器的更多相关文章
- C++学习基础四——顺序容器和关联容器
—顺序容器:vector,list,queue1.顺序容器的常见用法: #include <vector> #include <list> #include <queue ...
- 【mongodb系统学习之九】mongodb保存数据
九.mongodb保存数据: 1).插入.保存数据:insert:语法db.collectionName.insert({"key":value}),key是字段名,必须是字符串( ...
- Linux系统学习 十九、VSFTP服务—虚拟用户访问—为每个虚拟用户建立自己的配置文件,单独定义权限
为每个虚拟用户建立自己的配置文件,单独定义权限 可以给每个虚拟用户单独建立目录,并建立自己的配置文件.这样方便单独配置权限,并可以单独指定上传目录 1.修改配置文件 vi /etc/vsftpd/vs ...
- 系统学习 Java IO (九)----缓冲流 BufferedInputStream/BufferedOutputStream
目录:系统学习 Java IO---- 目录,概览 BufferedInputStream BufferedInputStream 类为输入流提供缓冲. 缓冲可以加快IO的速度. BufferedIn ...
- Docker学习(九)Volumn容器间共享数据
Docker学习(九)Volumn容器间共享数据 volume是什么 volume在英文中是容量的意思, 在docker中是数据卷的意思,是用来保存数据的容器 为什么要进行数据共享 在集群中有多台to ...
- Docker 容器数据 持久化(系统学习Docker05)
写在前面 本来是可以将数据存储在 容器内部 的.但是存在容器内部,一旦容器被删除掉或者容器毁坏(我亲身经历的痛,当时我们的大数据平台就是运行在docker容器内,有次停电后,不管怎样容器都起不来.以前 ...
- c++ 顺序容器学习
所谓容器,就是一个装东西的盒子,在c++中,我们把装的东西叫做“元素” 而顺序容器,就是说这些东西是有顺序的,你装进去是什么顺序,它们在里面就是什么顺序. c++中的顺序容器一共有这么几种: vect ...
- 【c++ Prime 学习笔记】第9章 顺序容器
一个容器是特定类型对象的集合 顺序容器中元素的顺序与其加入容器的位置对应 关联容器中元素的顺序由其关联的关键字决定,关联容器分为有序关联容器和无序关联容器 所有容器类共享公有接口,不同容器按不同方式扩 ...
- Unity3D 装备系统学习Inventory Pro 2.1.2 基础篇
前言 前一篇 Unity3D 装备系统学习Inventory Pro 2.1.2 总结 基本泛泛的对于Inventory Pro 这个插件进行了讲解,主要是想提炼下通用装备系统结构和类体系.前两天又读 ...
随机推荐
- layui时间控件联动:开始时间、结束时间,有效时间范围
实际开发中,经常遇到时间控件联动的情况,然后每次都网上搜代码Copy,不过每次都有点小Bug让你错不及防: 这次,在这里备份一下,以后Copy自己的得了(欢迎Copy代码,若遇到问题,请麻烦回复我一下 ...
- 登录案例version1 基本登录+验证码
package com.frxx.web.servlet; import com.frxx.domain.User; import com.frxx.service.impl.UserServiceI ...
- [题解](gcd/欧拉函数)luogu_P2568_GCD
求gcd(x,y)=p等价于求gcd(x/p,y/p)=1,转化为了n/p内互质的个数 所以欧拉函数,因为有序所以乘2,再特判一下只有在1,1情况下才会重复计算,所以每次都减一 数组开小一时爽,提交w ...
- Js $.merge() 函数(合并两个数组内容到第一个数组)
定义和用法 $.merge() 函数用于合并两个数组内容到第一个数组. 语法 $.merge( first, second ) 参数 描述 first Array类型 第一个用于合并的数组,合并后 ...
- BZOJ 1116: [POI2008]CLO 并查集
成立时当且仅当每个联通块都有环存在.一个连通块若有m个点,则必有多于m条有向边,可用并查集来维护. #include<cstdio> #include<iostream> #d ...
- Linux上安装Docker,并成功部署NET Core 2.0
概述 容器,顾名思义是用来存放并容纳东西的器皿: 而容器技术伴着Docker的兴起也渐渐的映入大家的眼帘,它是一个抽象的概念,同时也是默默存在世上多年的技术,不仅能使应用程序间完全的隔离,而且还能在共 ...
- Linux unzip用法
1.把文件解压到当前目录下 unzip test.zip 2.如果要把文件解压到指定的目录下,需要用到-d参数. unzip -d /temp test.zip 3.解压的时候,有时候不想覆盖已经存在 ...
- react-dnd
http://react-trello-board.web-pal.com/ https://react-dnd.github.io/react-dnd/docs-tutorial.html http ...
- (转) Linux命令详解-date
Linux命令详解-date 原文:https://www.cnblogs.com/Dodge/p/4278292.html 在linux环境中,不管是编程还是其他维护,时间是必不可少的,也经常会用到 ...
- Sql server 查询指定时间区间工作日数、休息日数等日期操作
1.查询指定时间区间的工作日 这个主要难点是法定节假日,国家的法定节假日每年都不一样,还涉及到调休,所以我们设计一个假日表.主要字段有年份,类型(是否调休),假期日期.如下: CREATE TABLE ...