C++ primer超详细讲解顺序容器

目录
  • 顺序容器概述
  • 容器库概览
    • 迭代器
    • 容器定义和初始化
    • 赋值和swap
  • 顺序容器操作
    • 向顺序容器添加元素
    • 访问元素
    • 删除元素
    • 特殊的forwa_list单向链表操作
    • 改变容器大小
  • vector对象是如何增长的

定义:一个容器就是一个特定类型对象的集合。

顺序容器概述

(1)顺序容器类型

vector:可变数组大小,支持快速访问

deque:双端队列,支持快速随机访问,在头尾位置插入/删除速度很快

forward_list:单向链表,只支持单向顺序访问。

array:固定大小数组,不能添加或删除元素

string:和vector类似,用来保存字符

容器库概览

迭代器

迭代器范围由一对迭代器表示,,通常被称为begin和end,而end从来都不会指向范围中的最后一个元素,而是指向尾元素之后的位置,其元素范围由数学表示为:

[begin,end)

容器定义和初始化

(1)将一个容器初始化为另一个容器的拷贝

可拷贝整个容器,也可以拷贝一个指定容器的元素范围

新容器和原容器的元素类型可以不同,只要能将要拷贝的元素转换为要初始化的元素的类型即可

list<string> authors={"nuktib","sha"m"aus"}
vector<const char *> articles={"a","an","the"}
list<string> list2(authors);      //正确,类型匹配
deque<string> authList(authors)   //错误,容器类型不匹配
forward_list<string> words(articles.begin(),articles.end())
//上述正确,可以将const char*元素转换为string

(2)与顺序容器大小相关的构造函数

其中一个构造函数接收一个容器大小和一个元素初始值

list<string> i(10,"hi")   //10个strings元素,每个都初始化为"hi"
vector<int> v(10,-1)     //10个int元素,每个都初始化为-1
deque<string> i(10)     //10个元素,每个都是空的string

(3)标准库array具有固定大小

定义一个array时,除了指定元素类型,还要指定容器大小

array<int,42>
array<string,10>

内置数组不支持拷贝或对象赋值操作,但array无此限制

int digs[10]={1,2,3}
int cpy[10]=digs   //错误,内置数组不支持拷贝和赋值
array<int,10> d={1,2,3,4,5,6,7}
array<int,10> c=d   //正确

赋值和swap

(1) assign赋值函数(仅顺序容器)

顺序容器定义了一个名为assign的成员,允许我们从一个不同但相容的类型赋值,或者从一个容器的子序列赋值。

例:

list<string> name;
vector<const char*>old;
name.assign(old.cbegin(),old.cend())

上述代码将name中的元素替换为迭代器指定范围中的元素的拷贝,assign的参数决定了容器中将有多少个元素以及他们的值是什么

(2)使用swap

swap操作交换两个相同类型容器的内容

vector<string> v1(10);
vector<string> v2(20);
上述交换结束后,v1将会拥有20个元素,v2将会拥有10个元素

顺序容器操作

向顺序容器添加元素

(1)使用push_back

除了array和forward_list之外,每个顺序容器都支持push_back

(2)push_front

list,forward_list,deque容器还支持push_front将元素插入容器头部

list<int> l;
for(int i=0;i!=4;i++)
    l.push_front(i)

(3)在特定位置添加元素

insert函数可在特定位置添加元素,每个insert元素都接受一个迭代器作为其第一个参数,insert函数将元素插入到迭代器所指得位置之前

虽然有些容器不支持push_front操作,但他们对于insert操作无此限制,因此可以将元素插入到容器开始的位置,不必担心容器是否支持push_front

insert另一个版本还接受一个元素数目和一个值,将指定数目的元素添加到指定位置之前。

s.insert(s.end(),10,"anna") //将10个元素插入到s的末尾

还可以接受一对迭代器或一个初始化列表插入

s.insert(s.end(),{"thses","as","sda","dasda"});

使用insert的返回值

list<string> l;
auto iter = l.begin();
string word;
while (cin >> word)
	iter = l.insert(iter, word);

上述代码实现在一个特定位置反复插入元素

第一次调用insert将刚刚读取的string插入到iter所指向的元素之前,insert返回的迭代器恰好指向这个新元素,我们将此迭代器赋予iter并重新开始循环,读取下一个单词,不断循环。

访问元素

所有顺序容器都存在一个front成员函数,,除了forward_list之外的所有顺序容器都由一个back成员函数,front成员函数返回首元素的引用,back成员函数返回尾元素的引用

可以通过该引用修改容器中元素的值

if(!c.empty())
{
    c.front()=42;
    auto &v=c.back()
    v=1024;
}

删除元素

(1)pop_front和pop_back成员函数分别删除首元素和尾元素,vector和string,forward_list不支持上述操作

(2)earse

成员函数erase从容器指定位置删除元素,也可以删除迭代器指定的单个元素,也可以删除由一对迭代器指定的范围内的所有元素,上述最终均会返回指向删除的元素之后位置的迭代器。

例:删除所有的奇数

list<int> ls = { 0,1,2,3,4,5,6,7,8,9 };
auto it = ls.begin();
while (it != ls.end())
{
	if (*it % 2)
		it = ls.erase(it);
	else
		it++;
}

接受一堆迭代器的erase版本允许我们删除一个范围内的元素:

例: s.erase(s.begin(),s.end())

特殊的forwa_list单向链表操作

单向链表中由于特殊的插入和删除,所以定义的函数也比较特殊

before_begin():返回指向链表首元素之前不存在的元素的迭代器,此迭代器不能解引用

insert_after(p,t):在迭代器p之后插入元素t

erase_after(p):删除p所指位置之后的元素

例:删除奇数元素:

forward_list<int> lst = { 0,1,2,3,4,5,6,7,8,9 };
auto pre = lst.before_begin();
auto cur = lst.begin();
while (cur != lst.end())
{
	if (*cur % 2)
		cur = lst.erase_after(pre);   //将cur重置为erase_after的返回值,即指向cur的下一个元素
	else
	{
		pre = cur;
		cur++;
	}
}

改变容器大小

通过resize函数可以改变容器的大小,但array不支持此操作

c.resize(n):调整c为n个元素

c.resize(n,t):调整c为n个元素,任何新添加的元素都初始化为t

vector对象是如何增长的

为了支持随机访问,vector将元素连续存储,当不得不获取新的内存控件时,vector和string通常会分配比新的控件需求更大的内存控件,容器预留这些空间作为备用,可以保存更多元素。

capacity函数告诉我们容器在不扩张内存空间情况下可以容纳多少元素

size():是指目前已经保存的元素的数目

reverse(n):告诉容器至少分配容纳n给元素的空间

到此这篇关于C++ primer超详细讲解顺序容器的文章就介绍到这了,更多相关C++顺序容器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++顺序容器(vector、deque、list)的使用详解

    目录 一:STL(Standard Template Library),即标准模板库,是一个高效的C++程序库 二:STL组件 三:容器 四:类型成员 五:迭代器 六:顺序容器 七:顺序容器--向量(vector) 八:顺序容器--双端队列--deque 九:顺序容器 --列表--list 一:STL(Standard Template Library),即标准模板库,是一个高效的C++程序库 1.从实现层次看,整个STL是以一种类型参数化(type parameterized)的方式实现的,基

  • C++(STL库)之顺序容器vector的使用

    一.特点 ①总的来说:可变大小数组.支持快速随机访问.在尾部之外的位置插入或删除元素可能很慢 ②元素保存在连续的内存空间中,因此通过下标取值非常快 ③在容器中间位置添加或删除元素非常耗时 ④一旦内从重分配,和原vector相关的指针,引用,迭代器都失效.内存重分配耗时很长 二.头文件.using声明 头文件:#include <vector> using声明:using std::vector; 三.初始化 vector<T>  v1; ==>v1是一个空的vector ve

  • C++ 标准模板库 STL 顺序容器详解

    C++ 标准模板库 STL 顺序容器 容器 数据结构 顺序性 重复性 支持迭代器 vector 动态数组 无序 可重复 随机访问迭代器 deque 双向队列 无序 可重复 随机访问迭代器 list 双向链表 无序 可重复 双向迭代器 动态数组 vector ​ vector #include <vector> 动态数组:其元素在内存中是连续存放的,随机存取任何元素都可以在常数时间内完成,在该容器的尾部增删元素也几乎能够在常数时间内完成具有较好的性能. ​ 一个 vector 常用函数使用实例如

  • C++Primer笔记之顺序容器的使用详解

    顺序容器,它将单一类型元素聚集起来成为容器,然后根据位置来存储和访问这些元素,这就是顺序容器.标准库里定义了三种类型:vector(支持快速随机访问).list(支持快速插入.删除).deque(双端队列)容器只定义了少量操作,大多数额外的操作由算法库提供.容器内元素的类型约束:1.元素类型必须支持赋值运算:2.元素类型的对象必须可以复制.这是容器元素类型的最低要求,如果想支持一些其他特殊要求,则必须具备相关的性质. 可以定义容器的容器vector< vector<int> > l

  • C++ primer超详细讲解顺序容器

    目录 顺序容器概述 容器库概览 迭代器 容器定义和初始化 赋值和swap 顺序容器操作 向顺序容器添加元素 访问元素 删除元素 特殊的forwa_list单向链表操作 改变容器大小 vector对象是如何增长的 定义:一个容器就是一个特定类型对象的集合. 顺序容器概述 (1)顺序容器类型 vector:可变数组大小,支持快速访问 deque:双端队列,支持快速随机访问,在头尾位置插入/删除速度很快 forward_list:单向链表,只支持单向顺序访问. array:固定大小数组,不能添加或删除

  • C++ primer超详细讲解关联容器

    目录 使用关联容器 关联容器概述 定义关联容器 pair类型 关联容器操作 关联容器迭代器 添加元素 删除元素 map的下标操作 访问元素 允许重复关键字的容器的名字开中都有包含单词multi,不保持关键字按顺序存储的容器的名字都以unordered开头. 使用关联容器 (1)经典的map程序 单词计数程序 map<string, size_t>word_count; string word; while (cin >> word) ++word_count[word]; for

  • C++ primer超详细讲解泛型算法

    目录 初识泛型算法 只读算法 写容器算法 定制操作 lambda表达式 lambda捕获和返回 再探迭代器 插入迭代器 iostream迭代器 反向迭代器 初识泛型算法 只读算法 只读取输入范围内的函数,不改变元素,find,accumula也是如此 (1)accumulate算法为求和算法,前两个参数指出求和元素范围,第三个是和的初值,例: int sum=accumulate(v.begin(),v.end(),0) (2)操作两个序列的算法 equal算法,确定两个序列是否保存相同的值,将

  • C++ 数据结构超详细讲解顺序表

    目录 前言 一.顺序表是什么 概念及结构 二.顺序表的实现 顺序表的缺点 几道练手题 总结 (●’◡’●) 前言 线性表是n个具有相同特性的数据元素的有限序列.线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表.链表.栈.队列.字符串. 线性表在逻辑上是线性结构,也就是说连续的一条直线,但是在物理结构并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储. 本章我们来深度初体验顺序表 一.顺序表是什么 概念及结构 顺序表是一段物理地址连续的存储单元依次存储数据元素的线性

  • C语言超详细讲解顺序表的各种操作

    目录 顺序表是什么 顺序表的结构体 顺序表的接口函数 顺序表相关操作的菜单 顺序表的初始化 添加元素 陈列元素 往最后加元素 往前面加元素 任意位置加元素 删除最后元素 删除前面元素 删除任意元素 整体代码(fun.h部分) 整体代码(fun.cpp部分) 整体代码(主函数部分) 结果展示 顺序表是什么 顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素.使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数

  • Java超详细讲解ArrayList与顺序表的用法

    目录 简要介绍 Arraylist容器类的使用 Arraylist容器类的构造 ArrayList的常见方法 ArrayList的遍历 ArrayList中的扩容机制 简要介绍 顺序表是一段物理地址连续的储存空间,一般情况下用数组储存,并在数组上完成增删查改.而在java中我们有ArrayList这个容器类封装了顺序表的方法. 在集合框架中,ArrayList是一个普通的类,其实现了list接口.其源码类定义如图 可见,其实现了RandomAccess, Cloneable, 以及Seriali

  • SpringBoot嵌入式Servlet容器与定制化组件超详细讲解

    目录 嵌入式Servlet容器 1.原理分析 2.Servlet容器切换 3.定制Servlet容器配置 定制化组件 嵌入式Servlet容器 在Spring Boot中,默认支持的web容器有 Tomcat, Jetty, 和 Undertow 1.原理分析 那么这些web容器是怎么注入的呢?我们一起来分析一下 当SpringBoot应用启动发现当前是Web应用,它会创建一个web版的ioc容器ServletWebServerApplicationContext 这个类下面有一个createW

  • SpringMVC超详细讲解视图和视图解析器

    目录 SpringMVC-视图和视图解析器 1.基本介绍 2.自定义视图 1.为什么要自定义视图 2.自定义视图实例-代码实现 3.自定义视图工作流程小结 自定义视图-小结 自定义视图-工作流程 4.目标方法直接指定转发或重定向 1.使用实例 2.指定请求转发流程-Debug源码 3.指定重定向流程-Debug源码 SpringMVC-视图和视图解析器 1.基本介绍 在 springMVC 中的目标方法最终返回都是一个视图(有各种视图). 返回的视图都会由一个视图解析器来处理 (视图解析器有很多

  • Spring Boot超详细讲解请求处理流程机制

    目录 1. 背景 2. Spring Boot 的请求处理流程设计 3. Servlet服务模式请求流程分析 3.1 ServletWebServerApplicationContext分析 3.2 Servlet服务模式之请求流程具体分析 4. Reactive服务模式请求流程分析 4.1 ReactiveWebServerApplicationContext分析 4.2 webflux服务模式之请求流程具体分析 5. 总结 1. 背景 之前我们对Spring Boot做了研究讲解,我们知道怎

  • Android LayerDrawable超详细讲解

    目录 1. 前言 2. 实例 1. 前言 Android LayerDrawble 包含一个Drawable数组,系统将会按照这些Drawable对象的数组顺序来绘制他们,索引最大的 Drawable 对象将会被绘制在最上面. LayerDrawable对象的xml文件的根元素是<layer-list>, 该元素内部包含多个<item>.item标签内部可以指定drawable.id和位置相关属性. layer-list可以进一步扩展对shape和selector的使用,对laye

随机推荐