C++(9):顺序容器

news2024/11/16 3:31:04

顺序容器概述

所有顺序容器都提供了快速顺序访问元素的能力。

vector//可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素可能很慢
deque//双端队列。支持快速随机访问。在头尾位置插入/删除速度很快
list//双向链表。只支持双向顺序访问。在list中任何位置进行插入/删除操作速度都很快
forward_list//单向链表。只支持单向顺序访问。在链表任何位置进行插入/删除操作速度都很快
array//固定大小数组。支持快速随机访问。不能添加或删除元素
string//与vector 相似的容器,但专门用于保存字符。随机访问快。在尾部插入/删除速度快

string 和 vector 将元素保存在连续的内存空间中。
由于元素是连续存储的,由元素的下标来计算其地址是非常快速的。但是,在这两种容器的中间位置添加或删除元素就会非常耗时:在一次插入或删除操作后,需要移动插入/删除位置之后的所有元素,来保持连续存储。而且,添加一个元素有时可能还需要分配额外的存储空间。在这种情况下,每个元素都必须移动到新的存储空间中。

list 和 forward list 两个容器任何位置的添加和删除操作都很快速。
作为代价,这两个容器不支持元素的随机访问:为了访问一个元素,我们只能遍历整个容器。而且,与vector、deque和 array相比,这两个容器的额外内存开销也很大。

deque 的中间位置添加或删除元素的代价很高,但在两端添加或删除元素很快。

array对象大小是固定的,不支持添加和删除元素以及改变容器大小的操作。

forward_list 没有 size 操作,forward_list 的设计目标是达到与最好的手写的单向链表数据结构相当的性能,保存或计算 forward_list 大小就会比手写链表多出额外的开销。

容器选择:

  • 没有特殊的理由,使用 vector 是最好的选择;
  • 有很多小的元素,不用 list 或 forward_list;
  • 随机访问元素,用 vector 和 deque;
  • 在容器中间插入或删除元素,用 list 和 forward_list;
  • 在头尾位置插入或删除元素,但不在中间位置插入或删除元素,用deque;
  • 在中间位置插入,而后随机访问:
    ①向 vector 中追加数据,再调用 sort 函数来排序;
    ②在输入阶段用 list ,输入完成后拷贝到 vector 中。

容器库概览

在这里插入图片描述
构造函数:同类拷贝、迭代器范围初始化、列表初始化

C c;//默认构造函数,构造空容器
C c1(c2);// 拷贝构造函数,容器类型与元素类型必须都相同,c2->c1
C c1(c2.begin(),c2.end());// 要求两种元素类型可以转换即可。
C c1{a,b,c,...};// 使用初始化列表,容器的大小与初始化列表一样大

赋值与 swap

c1=c2;//将c1中的元素替换为c2中的元素
c1={a,b,c...};//将c1中的元素替换为列表中的元素(不适用于 array)
a.swap(b);//交换a和b的元素
swap(a,b);//与a.swap(b)等价

大小

c.size();//c中元素的数目(不支持forward_list)
c.max_size();//c可保存的最大元素数目
c.empty();//若c中存储了元素,返回false,否则返回true

添加/删除元素

c.insert(args);    // 将 args 中的元素拷贝进 c
c.emplace(inits);  // 使用 inits 构造 c 中的一个元素
c.erase(args);     // 删除指定的元素
c.clear();

反向容器的额外成员
在这里插入图片描述

迭代器

迭代器范围由一对迭代器表示,两个迭代器表示的范围都是左闭合空间,即 [begin,end) :如果 begin 和 end 相等,则为空。
所有迭代器都可以递增,forward_list 不可以递减

// iter是通过list<string>定义的一个迭代器类型
list<string>::iterator iter;
//count是通过vector<int>定义的一个difference_type类型
vector<int>::difference_type count;

当不需要写访问时,应使用 cbegin和cend。加c后的版本是 const_iterator。

容器定义和初始化

当将一个容器初始化为另一个容器的拷贝时,两个容器的容器类型和元素类型都必须相同。

只有顺序容器的构造函数才接受大小参数,关联容器并不支持。

对 array 进行列表初始化,初始值的数目必须等于或小于 array 的大小。

array<int, 10>ial;//10个默认初始化的int
array<int,10> ia2 = {0,1,2,3,4,5,6,7,8,9};//列表初始化
array<int, 10>ia3 = (42); // ia3[0]为42,剩余元素为0

如果定义的 array 很大并且需要初始化,可以先默认初始化然后用 fill 函数填充值。
array 可以拷贝或赋值,使用一个 array 对另一个 array 赋值,需要两个array 元素类型与大小都相同。

赋值和 swap

在这里插入图片描述“=”赋值
对容器使用赋值运算符(除 array 外),将会使该容器的所有元素被替换。如果两个容器大小不等,赋值后都与右边容器的原大小相同。
array要求赋值前大小就必须一样。

assign:允许从一个不同但相容的类型赋值,或者从容器的一个子序列赋值。

list<string> names;
vector<const char*>oldstyle;
names = oldstyle;//错误:容器类型不匹配
//正确:可以将 const char* 转换为 string
names.assign (oldstyle.cbegin(),oldstyle.cend());

swap:除array外,交换两个容器内容的操作保证会很快—元素本身并未交换,swap 只是交换了两个容器的内部数据结构。

顺序容器操作

添加元素

在这里插入图片描述
向 vector、string 或 deque 插入元素会使所有指向容器的迭代器、引用和指针失效。
emplace函数在容器中直接构造元素。传递给emplace函数的参数必须与元素类型的构造函数相匹配。
emplace_front、 emplace 和 emplace_back 操作构造而不是拷贝元素。

访问元素

访问元素首先保证容器是非空的。

if(!c.empty()){}

在这里插入图片描述

删除元素

删除元素之前,首先要保证它是存在的。

在这里插入图片描述

特殊的 forward_list 操作

forward_list 是单向链表,添加和删除操作都会同时改变前驱和后继结点,因此一般的添加和删除都不适用于 forward_list。
在这里插入图片描述

改变容器大小

容器操作可能使迭代器失效

添加元素后:

  • 如果容器是vector或string,且存储空间被重新分配,则指向容器的迭代器、指针和引用都会失效。如果存储空间未重新分配,指向插入位置之前的元素的迭代器、指针和引用仍有效,但指向插入位置之后元素的迭代器、指针和引用将会失效。
  • 对于 deque,插入到除首尾位置之外的任何位置都会导致迭代器、指针和引用失效。如果在首尾位置添加元素,迭代器会失效,但指向存在的元素的引用和指针不会失效。
  • 对于 list和forward_list,指向容器的迭代器(包括尾后迭代器和首前迭代器)、指针和引用仍有效。

删除元素后:

  • 对于list和 forward list,指向容器其他位置的迭代器(包括尾后迭代器和首前迭代器)、引用和指针仍有效。
  • 对于 deque,如果在首尾之外的任何位置删除元素,那么指向被删除元素外其他元素的迭代器、引用或指针也会失效。如果是删除 deque 的尾元素,则尾后迭代器也会失效,但其他迭代器、引用和指针不受影响;如果是删除首元素,这些也不会受影响。
  • 对于vector和string,指向被删元素之前元素的迭代器、引用和指针仍有效。注意:当我们删除元素时,尾后迭代器总是会失效。

不要保存 end 返回的迭代器:push、pop、首尾 emplace 操作都没有返回值,但是都会改变尾后迭代器。

保证每次改变容器的操作之后都正确地重新定位迭代器

vector 对象

为了支持快速访问,vector 将元素连续存储。
为了避免每增加一个元素就要重新分配一次空间,在每次必须获取新的内存空间时,通常会分配比新的空间需求更大的内存空间。容器预留多的空间作为备用。

容量管理:
在这里插入图片描述
容器的size是指它已经保存的元素的数目;而capacity则是在不分配新的内存空间的前提下它最多可以保存多少元素。
c.reserve(n) 不会减小容量,只会增大容量,当需求容量大于当前容量,才会分配内存,否则什么都不做。
c.shrink_to_fit() 只是一个请求,实现时标准库可能会不执行。

额外的 string 操作

1.提供string类和C风格字符数组之间的相互转换;
2.允许用下标代替迭代器。

构造 string 的其他方法

//n, len2和pos2都是无符号值
string s(cp,n)//s是cp指向的数组中前n个字符的铂贝。此数组至少应该包含n个字符
string s (s2, pos2)//s是 string s2从下标 pos2开始的字符的铂贝。若pos2>s2.size(),构造函数的行为未定义
string s(s2,pos2,len2)//s是string s2从下标pos2开始len2个字符的拷贝。若pos2>s2.size (),构造函数的行为未定义。不管1en2的值是多少,构造函数至多拷贝s2.size ()-pos2个字符

substr 操作
substr操作返回一个string,它是原始string 的一部分或全部的拷贝。可以传递给substr一个可选的开始位置和计数值:

s.substr(pos, n)//返回一个string,包含s中从pos 开始的n个字符的铂贝。pos的默认值为0。n的默认值为s.size()-pos,即铂贝从pos 开始的所有字符

改变 string 的其他方法

在这里插入图片描述

string 搜索操作

string 搜索函数返回 string:: size_typ e值,该类型是一个 unsigned 类型。
在这里插入图片描述在这里插入图片描述

注意:find 和 rfind 查找的是给定的整个 args,而剩下的查找的是给定的 args 中包含的任意一个字符。

compare 函数

用于比较两个字符串,可以是比较整个或一部分字符串。
小于返回负数,大于返回正数,等于返回零。

int F = s.compare(s2);
int F = s.compare(pos1,n1,s2);          // 将 s 中 pos1 开始的前 n1 个字符与 s2 比较
int F = s.compare(pos1,n1,s2,pos2,n2);  // 将 s 中 pos1 开始的前 n1 个字符与 s2 中从 pos2 开始的 n2 个字符进行比较
int F = s.compare(cp)                   // 将 s 与 cp 指向的字符数组比较
int F = s.compare(pos1,n1,cp);
int F = s.compare(pos1,n1,cp,n2);

数值转换

string 与 数值之间的转换:
在这里插入图片描述

容器适配器

标准库定义了三个顺序容器适配器:stack、queue、priority_queue。
适配器是一种机制,是某种事物的行为看起来像另一种事物。

适配器类型
在这里插入图片描述
定义一个适配器
每个适配器都定义两个构造函数:默认构造函数创建一个空对象,接受一个容器的构造函数拷贝该容器来初始化适配器。

stack<int> stk(deq);//从deq拷贝元素到stk

默认情况下, stack 和 queue 是基于 deque 实现的, priority_queue 是在 vector 之上实现的。
在创建适配器时用一个顺序容器作为第二个类型参数,来重载默认容器类型:

//在vector上实现的空栈
stack<string, vector<string>> str_stk;
//str_stk2在vector上实现,初始化时保存svec的拷贝
stack<string, vector<string>> str_stk2(svec);

栈适配器

在这里插入图片描述
队列适配器
queue 和 priority_queue 都定义在头文件 queue 中。
queue 使用一种先进先出(first-in, first-out,FIFO)的存储和访问策略。队尾进,队首出。
priority_queue 允许为队列中的元素建立优先级。新加入的元素会排在所有优先级比它低的已有元素之前。

在这里插入图片描述在这里插入图片描述

重要术语

首前迭代器 :表示一个 forward_list 开始位置之前(不存在的)元素的迭代器。是 forward_list 的成员函数 befor_begin 的返回值。与 end() 迭代器类似,不能被解引用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/655704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

oVirt 4.4.10三节点超融合集群安装配置及集群扩容(二)

在上节安装完成3节点集群后&#xff0c;在此基础上扩容到6节点<oVirt每次扩容后的容量必须是3的倍数> 操作步骤 在原始第一台服务器访问https://192.168.5.100:9090/,在"Virtualiztion"->“Hosted Engin"下点击"Manage Gluster” 点击"Ex…

「已解决」已有Umi Antd 环境下安装 formily v2 依赖报错问题

背景 在一个项目中想引入 formily v2 试一下这个针对复杂表单的解决方案&#xff0c;结果发现安装后报错&#xff0c;目前已有的第三方库大致为 “ant-design/icons”: “^5.0.1”, “ant-design/pro-components”: “^2.4.4”, “umijs/max”: “^4.0.68”, “ahooks”: “^3…

【软考程序员学习笔记】——操作系统

目录 &#x1f34a;一、操作系统的五大功能 &#x1f34a;二、操作系统的分类 &#x1f34a;三、进程三态模型 &#x1f34a;四、信号量机制 &#x1f34a;五、PV机制、互斥和同步 &#x1f34a;六、虚拟存储器 &#x1f34a;七、设备管理 直接程序控制 &#x1f34a;八…

PyQt5桌面应用开发(21):界面设计结果自动测试(二)

本文目录 PyQt5桌面应用系列TDDUI为什么&#xff1f; 开发任务任务设计小码的工作unittest函数一览表 UI单元测试代码控件代码测试报告 总结 PyQt5桌面应用系列 PyQt5桌面应用开发&#xff08;1&#xff09;&#xff1a;需求分析 PyQt5桌面应用开发&#xff08;2&#xff09;&a…

Python基础(2)——Python解释器

Python基础&#xff08;2&#xff09;——Python解释器 文章目录 Python基础&#xff08;2&#xff09;——Python解释器目标一. 解释器的作用二. 下载Python解释器三. 安装Python解释器总结 目标 解释器的作用下载Python解释器安装Python解释器 一. 解释器的作用 Python解释…

Golang每日一练(leetDay0099) 单词规律I\II Word Pattern

目录 290. 单词规律 Word Pattern &#x1f31f;  291. 单词规律 II Word Pattern ii &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 …

ubuntu 20.04 arm 平台交叉编译 glib 库

glib 是什么&#xff1f; glib 是一个比较强大的 软件库&#xff0c;类似于 libc 库 交叉编译 当前需要移植到 arm&#xff08;ARM 32位&#xff09;平台上&#xff0c;需要使用 arm 交叉编译工具链编译 glib 环境准备 ubuntu 20.04 安装较新版本的 meson &#xff1a; &g…

手写-js节流(定时器+时间差两种方式)

官方解释&#xff1a;当持续触发事件时&#xff0c;保证一定时间段内只调用一次事件处理函数。 节流实现思路: 实现节流函数, 我们使用定时器是不方便管理的, 实现节流函数我们采用另一个思路 我们获取一个当前时间nowTime, 我们使用new Date().gettime()方法获取, 在设定一个…

[RPC]:Feign远程调用

文章目录 1 RPC框架-Feign1.1 什么是Feign1.2 Feign解决的问题1.2.1 使用RestTemplate发送远程调用代码1.2.2 存在的问题 1.3 Feign如何使用1.3.1 引入依赖 1 RPC框架-Feign 1.1 什么是Feign Feign是一个简化HTTP客户端编写的框架&#xff0c;通过声明式方式将远程服务调用封装…

基于html+css的图展示131

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

Three.js教程:平行光与环境光

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 其他系列工具&#xff1a; NSDT简石数字孪生 平行光与环境光 本节课通过平行光DirectionalLight (opens new window)和环境光AmbientLight (opens new window)进一步了解光照对应模型Mesh表面的影响。 点光源辅助观察Poin…

管理类联考——英语——技巧篇——新题型——经典方法论

新题型可以说是考研英语独有的考查形式&#xff0c;自2005年起&#xff0c;阅读理解部分便新增了PartB&#xff0c;即新题型。之所以叫作新题型&#xff0c;原因很简单&#xff0c;是因为它在考研英语的各个题型中&#xff0c;年龄是最小的&#xff0c;也就是最新的题型。新题型…

【MySQL表的增删改查】

MySQL表的增删改查 1. CRUD2. 新增&#xff08;Create&#xff09;2.1 单行数据 全列插入2.2 多行数据 指定列插入 3. 查询&#xff08;Retrieve&#xff09;3.1 全列查询3.2 指定列查询3.3 查询字段为表达式3.4 别名3.5 去重&#xff1a;DISTINCT3.6 排序&#xff1a;ORDER …

Hibernate框架【一】——HIbernate框架介绍

系列文章目录 Hibernate框架【三】——基本映射——一对一映射 Hibernate框架【四】——基本映射——多对一和一对多映射 Hibernate框架【五】——基本映射——多对多映射 Hibernate框架介绍 系列文章目录前言一、什么是HIbernate框架Hibernate架构图Hibernate提供的核心功能和…

php-xhprof 学习历程

听说 php-xhprof 可以分析网站的性能。今天闲来无事&#xff0c;就学习了一下。 1、安装&#xff08;万事都得从安装开始&#xff09; #首先&#xff0c;他是需要 graphviz 支持的。所以&#xff0c;我们得先安装这个依赖 yum install graphviz #就只需要这一行命令即可#下载地…

【C++】函数重载及引用

目录 一、函数重载 1、函数重载的概念 2、名字修饰 二、引用 1、引用概念 2、引用特性 3、常引用 4、引用的使用场景 4.1 做参数 4.2 做返回值 5、传值、传引用效率比较 6、引用和指针的区别 一、函数重载 1、函数重载的概念 函数重载&#xff1a;是函数的一种特殊情况&#…

leetcode415. 字符串相加

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【LeetCode】 &#x1f353;希望我们一起努力、成长&#xff0c;共同进步。 题目链接 给定两个字符串形式的非负整数 num1 和num2 &#…

OpenCV项目开发实战-- 的单应性(Homography)实例Python/C++代码实现

文末附基于Python和C++两种方式实现的测试代码下载链接 什么是单应性(Homography)? 考虑图 1 中所示的平面(书的顶部)的两个图像。红点表示两个图像中的相同物理点。在计算机视觉术语中,我们称这些为对应点。图 1. 显示了四种不同颜色的四个对应点——红色、绿色、黄色和…

【运维知识进阶篇】zabbix5.0稳定版详解1(安装+部署+添加服务器+拆分数据库)

本篇文章介绍zabbix监控&#xff0c;监控是对我们操作系统进行不间断的监控&#xff0c;这是软件生命周期非常重要的一环&#xff0c;可以做到事前告警&#xff0c;事后根据监控内容排查问题&#xff08;金丝雀&#xff0c;监控重要指标&#xff09;&#xff0c;有问题的时候&a…

chatgpt赋能python:Python安装和设置环境变量教程

Python安装和设置环境变量教程 Python是一门非常流行的编程语言&#xff0c;很多开发者都喜欢使用它开发各种应用程序。作为使用Python编程的开发者&#xff0c;你需要安装Python并设置环境变量。在本文中&#xff0c;我们将向你介绍如何安装Python&#xff0c;以及如何设置环…