C++顺序容器知识总结
容器是一种容纳特定类型对象的集合。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=;i!=;++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++ PRIMER》 中文版
C++顺序容器知识总结的更多相关文章
- C++关联容器知识总结
C++的容器类型可以分为顺序容器和关联容器两大类.顺序容器的知识可以参看我上篇的随笔<C++顺序容器知识总结>.关联容器支持通过键值来高效的查找和读取元素,这是它和顺序容器最大的区别.两种 ...
- C++ 顺序容器基础知识总结
0.前言 本文简单地总结了STL的顺序容器的知识点.文中并不涉及具体的实现技巧,对于细节的东西也没有提及.一来不同的标准库有着不同的实现,二来关于具体实现<STL源码剖析>已经展示得全面细 ...
- C++系统学习之九:顺序容器
元素在顺序容器中的顺序与其加入容器时的位置相对应.关联容器中元素的位置由元素相关联的关键字值决定.所有容器类都共享公共的接口,不同容器按不同方式对其进行扩展. 一个容器就是一些特定类型对象的集合.顺序 ...
- c++ 顺序容器学习
所谓容器,就是一个装东西的盒子,在c++中,我们把装的东西叫做“元素” 而顺序容器,就是说这些东西是有顺序的,你装进去是什么顺序,它们在里面就是什么顺序. c++中的顺序容器一共有这么几种: vect ...
- C++ Primer 第九章 顺序容器
由于书籍上写的已经很经典了,故大部分用图片的形式来阐述概念,代码纯手打进行验证. 1.顺序容器类型:vector.deque.list.forword_list.array.string. 2.顺序容 ...
- C++学习基础四——顺序容器和关联容器
—顺序容器:vector,list,queue1.顺序容器的常见用法: #include <vector> #include <list> #include <queue ...
- C++ 顺序容器
<C++ Primer 4th>读书笔记 顺序容器内的元素按其位置存储和访问.容器类共享公共的接口,每种容器类型提供一组不同的时间和功能折衷方案.通常不需要修改代码,只需改变类型声明,用一 ...
- C++ Primer : 第九章 : 顺序容器的操作以及迭代器失效问题
顺序容器的添加.访问.删除操作以及forward_list的特殊操作,还有迭代器失效问题. 一.向容器添加元素 // array不支持这些操作 // forward_list有自己撰于的版本的inse ...
- C++ Primer : 第九章 : 顺序容器的定义、迭代器以及赋值与swap
顺序容器属于C++ STL的一部分,也是非常重要的一部分. 顺序容器包括: std::vector,包含在头文件<vector>中 std::string, 包含在头文件<strin ...
随机推荐
- error: No curses/termcap library found的解决办法
mysql版本:5.1.30 已经不记得这次是第几次安装mysql了,遇到这个问题倒是第一次. 之前在tar,./configure,make,make install 经典四步时,从来没有想过其中的 ...
- discuz 更换域名 导致qq登录不能用的问题
今天论坛换了域名,导致qq登录不能用.于是各种百度,终于找到了解决方案,特此记录一下 解决方法:1,首先清空你站点的id和key,并且设置为未注册云平台: 2,找一个新域名(未开过云平台的就可),如果 ...
- ip2long的用法
ip2long:将IPv4的ip地址(以小数点分隔形式)转换为int Description int ip2long ( string ip_address ) 如果ip地址非法,返回FALSE(PH ...
- IBM Rational AppScan:跨站点脚本攻击深入解析
IBM Rational AppScan:跨站点脚本攻击深入解析 了解黑客如何启动跨站点脚本攻击(cross-site scripting,XSS),该攻击危害(及不危害)什么,如何检测它们,以 ...
- bootrom脚本的创建
bootrom脚本的创建 以下以压缩版bootrom 为例,基于Powerpc 平台,详细介绍压缩版bootrom 的生成过程及执行流程,从而使读者对bootrom有一个彻底的了解.这对于Vx ...
- Linux显示以时间生升序显示文件
Linux显示以时间生升序显示文件 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ls -lnt 总用量 56 -rw-rw-r-- 1 1000 1000 ...
- CentOS修改root密码
1.在系统启动时,按任意键中止启动 2.按E键修改系统启动文件 3.找到linux16开头的行,把整行ro后面内容删除,添加rd.break 4.Ctrl+X更改并重启 5.重新挂载/sysroot ...
- pat1061-1070
1061 我想吐槽这题的题意不够清楚,不过下次得长记性,对于模糊的题意要大胆猜测,而不是固执己见 #include<iostream> #include<cstdio> #in ...
- 非空校验的提示按钮(shiro项目中来的六)
一:图示 二,js脚本 /** * jquery tips 提示插件 jquery.tips.js v0.1beta * * 使用方法 * $(selector).tips({ //selector ...
- 浏览器全屏之requestFullScreen全屏与F11全屏
一.简介 浏览器全屏有两种方式,一种是HTML5新增的requestFullscree全屏,另一种是摁F11实现的全屏,本文将详解两种全屏的特点以及实现代码. 二.requestFullscreen全 ...