c++11の顺序容器
容器是一种容纳特定类型对象的集合。C++的容器可以分为两类:顺序容器和关联容器。顺序容器的元素排列和元素值大小无关,而是由元素添加到容器中的次序决定的。标准库定义了三种顺序容器的类型:vector、list和deque(双端队列)。此外,标准库还提供了三种容器适配器:stack、queue和prioroty_queue类型。适配器是根据原始的容器类型所提供的操作,通过定义新的操作接口,来适应基础的容器类型。见下表

顺序容器
vector 支持快速随机访问
list 支持快速插入/删除
deque 双端队列
顺序容器适配器
stack 后进先出(LIFO)栈
queue 先进先出(FIFO)队列
priority_queue 有优先级管理的队列

一.定义和初始化
定义一个容器类型的对象之前,必须包含相关的头文件。如下:
#include<list>
#include<vector>
#include<deque>
所有容器都定义了默认构造函数,可以用默认构造函数来初始化一个空的容器对象,如下:
list<int> ilist;
此外,容器还有几种构造函数,可以用来初始化容器对象,如下:
C<T> c 创建一个名为c的空容器。C是容器名,T是元素类型。适用于所有容器
C c(c2) 创建容器c2的副本c。两者必须是相同类型的容器和元素。适用于所有容器
C c(b,e) 创建c,其元素是迭代器b和e标记范围内元素的副本。适用于所有容器
C c(n,t) 用n个值为t的元素创建c,其中t必须是容器类型C的元素类型的值或者是可以转化为该类型的值。只适用于顺序容器
C c(n) 创建n个初始化元素的容器c。只适用于顺序容器
值得注意到是,接受容器大小做形参的构造函数只适用于顺序容器,不适用于关联容器。由于指针就是迭代器,因此我们还可以通过使用内置数组中的一对指针初始化容器:
char *words[]={"Hi","How","Are","You“};
size_t words_size=sizeof(words)/sizeof(char *);
// 使用整个数组初始化words
list<string> words2(words,words+words_size);
前面我们说过,容器是存储某中类型元素的集合,所以可以定义元素是容器类型的容器。例如,可以定义vector类型的容器ivec,其元素为string类型的vector。但是注意,在指定容器元素为容器类型时,必须使用如下空格:
vector< vector<string> > ivec; //合法。在两个>之间有空格
vector<vector<string>> ivec; //错误。在两个>之间没有空格,>>会导致歧义
二.常用操作
顺序容器内置了一些有用的操作:(1)在容器中添加元素;(2)在容器中删除元素;(3)设置容器大小;(4)(如果有的话)获取容器内的第一个和最后一个元素。
1.begin和end
begin和end操作产生指向容器内第一个元素和最后一个元素的下一位置的迭代器。此外还有逆序迭代器(逆序迭代器从后向前遍历容器,并反转了某些相关的迭代器操作)rbegin和rend。如下:
c.begin() 返回一个迭代器,它指向容器c的第一个元素
c.end() 返回一个迭代器,它指向容器c的最后一个元素的下一个位置
c.rbegin() 返回一个逆序迭代器,它指向容器c的最后一个元素
c.rend() 返回一个逆序迭代器,它指向容器c的第一个元素的前一个位置
2.容器添加元素操作
下表为在顺序表中添加元素的操作。注意其中的适用范围和返回类型。
c.push_back() 在容器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类型
其中push_front只适用于list和deque容器类型,这个操作实现在首部插入新元素的功能。
//用push_front在容器尾部依次添加0,1,2,3
list<int> ilist;
for(size_t i=0;i!=4;++i)
ilist.push_front(i);
//ilist内元素序列为:3,2,1,0
需要注意的是,任何insert或push操作都可以导致迭代器失效。所以在编写循环将元素插入到vector和deque容器中时,程序必须确保迭代器在每次循环后都的到更新。

vector<string> ivec;
vector<string>::iterator iter=ivec.begin();
while(cin>>word)
iter=ivec.insert(iter,word); //效果和push_back一样 //以下是错误的,因为此时iter已经失效
vector<string> ivec;
vector<string>::iterator iter=ivec.begin();
while(cin>>word)
ivec.insert(iter,word); //错误,经过一轮的insert后iter即失效,不能再调用

3.容器大小的操作
所有容器都提供以下与容器大小相关的操作。注意resize操作可能会使迭代器失效。
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
在vector和deque容器上做resize操作有可能会使其所有迭代器都失效。对于所有的容器类型,如果resize操作压缩了容器,则指向已删除的元素的迭代器会失效。
4.访问容器元素的操作
以下为访问容器元素的操作。注意·使用越界的下标,或调用空容器的front或back函数,都会导致程序出现严重的错误。
c.back() 返回容器c的最后一个元素的引用。如果c为空,则该操作未定义
c.front() 返回容器c的第一个元素的引用。如果c为空,则该操作未定义
c[n] 返回下标为n的元素的引用。如果n<0或n>=c.size(),则该操作未定义。只适用于vector和deque容器
c.at(n) 返回下标为n的元素的引用。如果下标越界,则该操作未定义。只适用于vector和deque容器
5.删除容器元素的操作
以下为删除容器元素的操作。删除操作会使一些迭代器失效,需要特别注意。下表第一个操作在删除元素前,必须保证迭代器不是指向end的迭代器。

c.erase(p) 删除迭代器p指向的元素。返回一个迭代器,它指向被删除元素后面的元素。如果p指向容器内最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。
如果p本身就是超出容器末端的下一个位置,则该函数未定义
c.erase(b,e) 删除迭代器b和e所标记的范围内所有元素。返回一个迭代器,它指向被删除元素段后面的元素。如果e本身就是指向超出容器末端的下一个位置,
则返回的迭代器也指向容器末端的下一个位置
c.clear() 删除容器c内的所有元素。返回void
c.pop_back() 删除容器c的最后一个元素。返回void。如果容器为空,则该函数未定义
c.pop_front() 删除容器c的第一个元素。妇女会void。如果容器为空,则该函数未定义。只适用于list和deque容器
6.容器的赋值与swap操作
下表为顺序容器的赋值操作。赋值后左右两边容器相等,尽管赋值之前两个容器的大小不同,但赋值之后两个容器的长度都为右操作数的长度。
c1=c2 删除容器c1的所有元素,然后将c2的元素复制给c1。c1和c2的类型必须相同
c1.swap(c2) 交换c1和c2的内容,c1和c2的类型必须相同。其效率比把c2元素复制到c1中要高
c.assign(b,e) 重新设置c的元素:将迭代器b和e标记范围内的元素复制到c中。b和e必须不是指向c中元素的迭代器
c.assign(n,t) 将容器c重新设置为存储n个值为t的元素
c++11の顺序容器的更多相关文章
- C++ 顺序容器基础知识总结
0.前言 本文简单地总结了STL的顺序容器的知识点.文中并不涉及具体的实现技巧,对于细节的东西也没有提及.一来不同的标准库有着不同的实现,二来关于具体实现<STL源码剖析>已经展示得全面细 ...
- C++ Primer 5th 第9章 顺序容器
练习9.1:对于下面的程序任务,vector.deque和list哪种容器最为适合?解释你的选择的理由.如果没有哪一种容器优于其他容器,也请解释理由.(a) 读取固定数量的单词,将它们按字典序插入到容 ...
- c/c++ 标准顺序容器 之 push_back,push_front,insert,emplace 操作
c/c++ 标准顺序容器 之 push_back,push_front,insert,emplace 操作 关键概念:向容器添加元素时,添加的是元素的拷贝,而不是对象本身.随后对容器中元素的任何改变都 ...
- C++ Primer 笔记——顺序容器
1.标准库中定义了一些顺序容器,所有顺序容器都提供了快速顺序访问元素的能力. 2.如果容器的元素类型没有默认构造函数,那么在构造这个容器的时候不能只指定这个容器的数目,因为没有办法默认构造这些元素. ...
- c++11 List 容器
c++11 List 容器 List简介 list是一个双向链表容器 可高效地进行插入删除元素. list不可以随机存取元素,所以不支持at(pos)函数与[]操作符. ...
- Chapter9(顺序容器) --C++Prime笔记
PS:删除元素的成员函数并不检查其参数.在删除元素之前,程序员必须确保它们是存在的. 1.迭代器的范围是[begin,end)左闭右开. 2.对构成迭代器的要求: ①它们指向同一个容器中的元素或者容器 ...
- C++ 顺序容器原理
容器分为顺序容器与关联容器,顺序容器也称为序列式容器.序列式容器按元素插入的顺序存储元素,这些元素可以进行排序,但未必是有序的.C++本身内置了一个序列式容器array(数组),STL另外提供了vec ...
- [C++ Primer] 第9章: 顺序容器
顺序容器概述 顺序容器的类型有: 类型 说明 vector 可变长度数组. 支持快速随机访问. deque 双端队列. 支持快速随机访问. list 双向链表. 只支持双向顺序访问. forward_ ...
- C++中如何在顺序容器中删除符合特定条件的元素
以前很少做删除操作,vector一直当成数组用,而实际追求效率时又经常舍弃vector选用C风格数组.看<C++ Primer>到顺序容器删除这节时试着实现课后习题结果一动手我就出错了. ...
随机推荐
- Linux 初始环境配置 以及避坑 (详细)
没事儿喜欢自己装个虚拟机捣鼓捣鼓,经过几次装一些Linux 经验, 有时候 电脑了 .想重新系统了,又要重新去配置环境, 有时候又要去查很多很多命令 . 记录分享下Linux 下配置开发环境以及桌面 ...
- Prncnfg.vbs参数详解
语法: Cscript Prncnfg {-g | -t | -x | -?} [-S <ServerName>] [-P <PrinterName>] [-z <New ...
- JNA 备注
最近写JNA调用DLL的代码比较多.应该这样说,C的精华在于对指针的灵活运用,而用JNA调用C/C++最痛苦的也在于此.你不知道该用什么样的方式去对应C/C++的方法,特别是遇到指针.结构体指针.指针 ...
- 开启全民窃听风云——C#智能录音录像录屏程序源码放送!
·引子 我这人从小有个坏毛病,就是喜欢偷窥别人隐私.当然,在道德上,我时刻要求自己做一名正人君子,只不过是心理上有这癖好罢了.所以我从小就对窃听.窃视.黑客技术.破解技术等疯狂着迷!实际上这也是我走上 ...
- Django+xadmin打造在线教育平台(一)
目录 在线教育平台(一) 在线教育平台(二) 在线教育平台(三) 在线教育平台(四) 在线教育平台(五) 在线教育平台(六) 在线教育平台(七) 在线教育平台( ...
- 在dotnet core下去中心化访问HTTP服务集群
一般应用服务都会部署到多台服务器之上,一.可以通过硬件得到更多的并发处理能力:二.可以避免单点太故障的出现,从而确保服务7X24有效运作.当访问这些HTTP服务的情况一般都是经过反向代理服务进行统一处 ...
- js实现二分查找算法
二分查找:是一种搜索某个值的索引的算法. 基本条件:有序的数组. 思路:1.将数组折半,分成左右两个数组. 2.判断要查找的数和中间位置数值的大小,来判断要查找的数实在哪一半. 3.之后继续折半查找, ...
- Java中的基本类型转换,数据溢出原理
java中的数据类型 java是一种强类型语言,在java中,数据类型主要有两大类,基本数据类型和引用数据类型,不同的数据类型有不同的数据存储方式和分配的内存大小. 基本数据类型中,各数据类型所表示的 ...
- [Linux] deepin与nginx
deepin Linux Deepin 是一个基于 DEB 包管理的一个独立操作系统,和那些 Ubuntu(下个大版本是基于debian开发) 的衍生版仅仅只是换主题.调整ISO预置的软件包不同.Li ...
- axios(封装使用、拦截特定请求、判断所有请求加载完毕)
博客地址:https://ainyi.com/71 基于 Promise 的 HTTP 请求客户端,可同时在浏览器和 Node.js 中使用 vue2.0之后,就不再对 vue-resource 更新 ...