《C++ Primer》第9章 顺序容器(二)

参考资料:

  • 《C++ Primer》第5版
  • 《C++ Primer 习题集》第5版

9.3 顺序容器操作(P305)

9.3.1 向容器中添加元素(P305)

00418ca61cd635e0a466446a21be4f7

使用push_back

arrayforward_list 外,每个顺序容器都支持 push_back

vector<string> sentence;
while(cin >> word){
    sentence.push_back(word);
}

push_back 的调用相当于在容器尾部创建了一个新元素,将容器的 size 增大 1 ,该元素的值为 word拷贝

使用push_front

listforward_listdeque 还支持 push_front 操作,顾名思义就是把元素添加到容器头部。

在容器的特定位置添加元素

insert 提供了更一般的添加元素功能,它允许我们在容器中任意位置添加 0 个或多个元素。

每个 insert 函数都接受一个迭代器参数作为第一个参数,表示将元素插入到该迭代器所指位置之

插入范围内元素

insert 函数还可以接受更多参数,方式和容器构造函数类似:

vector<string> vs;
list<string> ls = {"hello", "world", "hi"};
vs.insert(vs.begin(), 10, "hi");
vs.insert(vs.begin(), ls.begin(), ls.end());
vs.insert(ls.begin(), ls.begin(), ls.end());    // 错误,拷贝范围和添加位置不能来自同一个容器

在新标准下,insert 返回第一个新加入元素的迭代器,如果没有新加入元素,则将参数迭代器返回。

使用insert的返回值

vector<int> vi = {0, 1, 2, 3, 4, 5};
auto it = vi.begin();
while(it != vi.end()){
    if(*it % 2){
        vi.insert(it, *it);
    }
    it++;
}
// vi的内容:0 1 1 2 3 3 4 5 5 

使用emplace操作

新标准引入了 emplace_frontemplaceemplace_back ,这些操作构造而不是拷贝元素。

调用 emplace 成员时,将参数传递给元素类型的构造函数直接构造元素:

// 使用三个参数的Sales_data构造函数
c.emplace_back("978-0590353403", 25, 15.99);

在调用 emplace_back 会在容器管理的内存空间中直接创建对象,push_back 则会创建一个局部临时对象,并将其压入容器中。

9.3.2 访问元素(P309)

f157ec230c56e627bb80437460f9693

访问成员函数返回的是引用

frontbackat 和下标返回的都是引用

下标操作和安全的随机访问

提供快速随机访问的容器都提供下标运算符越界的下标是一种严重的程序错误,而且编译器不会检查这种错误。

如果我们希望下标是合法的,可以使用 at 成员函数,如果下标越界,at 会抛出 out_of_range 异常。

9.3.3 删除元素(P311)

dd78ce4fc7a057ca0fc59432d94b8f5

pop_frontpop_back成员函数

二者的返回值均为 void

从容器内部删除一个元素

erase 从容器指定位置删除元素,可以删除一个由迭代器指定的单个元素,也可以删除由一对迭代器指定范围内的所有元素,返回删除的最后一个元素之后位置的迭代器。

// 删除奇数元素
vector<int> vi = { 0,1,2,3,4,5,6,7,8,9 };
auto cur = vi.begin();
while (cur != vi.end()) {
	if (*cur % 2) {
		cur = vi.erase(cur);
	}
	else {
		cur++;
	}
}

删除多个元素

vi.erase(vi.begin(), vi.end());

9.3.4 特殊的forward_list操作

回忆我们在数据结构中学过的知识,在单向链表中删除元素,往往需要用到待删除元素的上一个元素

由于删除方式的限制,forward_list 定义了 insert_afteremplace_aftererase_after 操作,也定义了 before_begin 来返回首前(off-the-beginning)迭代器

forward_list 中添加或删除元素时,我们必须同时关注指向待删除元素的迭代器和指向其前驱的迭代器:

// forward_list版删除奇数元素
forward_list<int> fi = { 0,1,2,3,4,5,6,7,8,9 };
auto pre = fi.before_begin();
auto cur = fi.begin();
while (cur != fi.end()) {
    if (*cur % 2) {
        cur = fi.erase_after(pre);
    }
    else {
        pre = cur;
        ++cur;
    }
}

9.3.5 改变容器大小(P314)

81e42c069a44d881ee3262939196fc8

我们可以用 resize 函数来增大或缩小容器,如果当前大小大于要求大小,容器后部的元素会被删除;如果当前大小小于要求大小,则会将新的元素添加到容器后面:

forward_list<int> fi = { 0,1,2,3,4,5,6,7,8,9 };
fi.resize(5);    // fi的内容:0,1,2,3,4
fi.resize(10, 5);    // fi的内容:0 1 2 3 4 5 5 5 5 5

9.3.6 容器操作可能使迭代器失效(P315)

向容器中添加元素或从容器中删除元素可能令指向容器元素的指针、引用、迭代器失效

向容器添加元素后:

  • 如果容器是 vectorstring ,且容器空间被重新分配,则指向容器的所有迭代器、指针、引用都会失效;如果容器空间没有被重新分配,则指向插入位置之前的元素的迭代器、指针、引用不会失效插入位置之后的迭代器、指针、引用会失效
  • 对于 deque 插入到除首尾位置之外的任何位置都会导致迭代器、指针、引用失效;如果在首尾位置添加元素,只会导致迭代器失效。
  • 对于 listforward_list ,指向容器的迭代器(包括尾后、首前)、引用、指针仍然有效。

从容器删除元素后:

  • 对于 listforward_list ,指向容器其他位置的迭代器(包括尾后、首前)、引用、指针仍然有效。
  • 对于 deque ,如果在首尾之外的任何位置删除元素,指向该容器中元素的迭代器、指针、引用都会失效;如果删除 deque 的尾元素,则尾后迭代器会失效,其他迭代器、指针、引用不受影响;如果删除首元素,除尾后迭代器外的其他迭代器、指针、引用不受影响(尾后迭代器是否会失效书里没说清楚)。
  • 对于 vectorstring ,指向被删元素之前元素的迭代器、指针、引用仍然有效,尾后迭代器总是会失效

不要保存end返回的迭代器

如果在一个循环中插入、删除 dequestringvector 中的元素,不要缓存 end 返回的迭代器。

9.4 vector对象是如何增长的

为了支持快速随机访问,vector 将元素存储在一片连续的空间中。如果添加元素时,vector没有足够的空间容纳新的元素,容器必须重新分配新的内存空间,将已有元素从旧位置移动到新空间中,然后添加新元素释放旧存储空间。

如果我们每添加一个元素就重新分配一次元素,那么性能将非常低。为此,标准库实现者通常会分配比需求更大的新内存空间,此时 vector 的扩张速度通常比 listdeque 还快。

管理容量的成员函数

e9bf4cce53b128bbca9b5913620623f

如果需求大小大于当前容量,reserve 至少分配与需求一样大的空间;如果需求大小小于等于当前容量,reserve 什么都不做。也就是说,调用 reserve 后,capacity 将大于传递给 reserve 的参数。

resize 成员只改变容器中的元素数量,而不是容器的容量:

// VS2022
vector<int> vi = {0};    // capacity = 1
vi.reserve(0);    // capacity = 1
vi.reserve(100);    // capacity = 100
vi.resize(0);    // capacity = 100, size = 0

shrink_to_fit 可以减少容器的容量,但其只是一个请求,具体的实现可以忽略此请求。

capacitysize

每个 vector 实现 都可以选择自己的内存分配策略,但必须遵守一条原则:只有当迫不得已时才可以重新分配策略。

通常来说,在一个空的 vector 上调用 n 次 push_back 的时间复杂度不能超过 n 的常数倍。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在windows下vs c++运行g2o的BA优化程序示例

目录 1、前言2、准备工作安装git安装vcpkg&#xff08;1&#xff09;下载&#xff08;2&#xff09;安装&#xff08;3&#xff09;集成至vs 安装cmake 3、安装g2o4、安装opencv&#xff08;1&#xff09;下载&#xff08;2&#xff09;双击安装&#xff08;3&#xff09;环境变…

Java反射机制开发经验总结

原创/朱季谦 反射是框架底层的灵魂&#xff0c;无论是Spring还是Dubbo&#xff0c;底层都大量使用到反射机制。 可以说&#xff0c;反射是Java开发当中一个绕不过的坎。 我曾经在实际项目当中有经常用到反射机制&#xff0c;故而将学会的反射用法做一些汇总笔记&#xff0c;当…

超详细的Jmeter随机参数各种搭配

前言 参数配置应该有三种场景&#xff0c;具体其他的我还没想到&#xff0c;那到底是哪三种呢&#xff1f;如果你也对这个问题感兴趣的话&#xff0c;那就让我们一起往下看吧&#xff01; 一、两个固定值之间随机生成一个值&#xff0c;应用场景没有限制 1、最简单的两个值之…

Spring lOC的注解使用与开发

Spring Spring IoC注解式开发为什么使用注解Spring注解的使用Value注解Autowired注解全注解式开发 Spring IoC注解式开发 为什么使用注解 注解的存在主要是为了简化XML的配置&#xff0c;注解的开发能大大提高我们的开发效率的&#xff0c;但它在一定程度上违背了OCP原则。 …

锐捷软件开机自启动

http://t.csdnimg.cn/h6k9R win键搜索任务计划程序 打开&#xff0c;在windows创建任务&#xff1a;

MAC地址_MAC地址格式_以太网的MAC帧_基础知识

MAC地址 全世界的每块网卡在出厂前都有一个唯一的代码,称为介质访问控制(MAC)地址 一.网络适配器(网卡) 要将计算机连接到以太网&#xff0c;需要使用相应的网络适配器(Adapter)&#xff0c;网络适配器一般简称为“网卡”。在计算机内部&#xff0c;网卡与CPU之间的通信&…

【智能家居项目】FreeRTOS版本——将裸机程序改造成FreeRTOS程序 | DHT11温湿度传感器

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《智能家居项目》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 如上图所示是裸机版本的智能家居项目总体框架结构&#xff0c;这篇文章开始&#xff0c;本喵要…

服装供应链管理的革新利器—超高频RFID技术

一、行业概述 服装行业一直被视为低技术含量的劳动密集型产业&#xff0c;但实际上&#xff0c;科学技术在整个行业的发展中起着至关重要的作用&#xff0c;从服装面料的制作到服装设计、生产制作、物流到终端销售&#xff0c;科技力量贯穿于每一个环节。然而&#xff0c;传统…

Codeforces Round 908 (Div 2——AB)

A. Secret Sport 题目 AB二人玩游戏&#xff0c;每一局&#xff08;plays&#xff09;游戏会有一个获胜者&#xff0c;首先获胜X局&#xff08;play&#xff09;的玩家得一分&#xff08;赢得一轮sets&#xff09;。率先获得Y分的玩家获得最终胜利。 给你整场游戏的每局&…

树状图PPT怎么做?用这个树状图制作软件轻松拿捏!

在我们的日常工作和学习中&#xff0c;PPT已经成为了我们常见的展示方式。 在制作PPT时&#xff0c;树状图PPT是非常重要和常用的一种&#xff0c;并且在商务、教育等领域都非常受欢迎。那么&#xff0c;究竟什么是树状图PPT&#xff0c;如何使用树状图制作软件来快速绘制树状…

2022年12月 Scratch(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

一、单选题(共25题,每题2分,共50分) 第1题 小明想在开始表演之前向大家问好并做自我介绍,应运行下列哪个程序?( ) A: B: C: D: 答案:D 外观积木配合显示时间,才能看清楚内容。 第2题 舞台有两个不同的背景,小猫角色的哪个

网站提示Internal Server Error的原因和解决方法分享

解决方法 登陆FTP或文件管理器,检查站点目录文件权限设置,将文件夹权限设置为755,单个文件权限设置为644。 这样设置644后,问题就可以解决,同时也不会影响网站的所需要的写入权限,满足网站正常运行。如果你的站点中有很多权限都要需要设置,为了提高效率。 应用导致分析…

案例分析:大疆的电子产品说明书在组织分类结构方面值得借鉴的地方

大疆科技作为全球领先的无人机和航拍设备制造商&#xff0c;其产品众多&#xff0c;包括无人机、相机等电子产品。为了提供给用户详尽准确的产品信息和操作指导&#xff0c;大疆在其官方网站上建立了一个电子产品说明书的帮助中心。在组织分类结构方面&#xff0c;大疆的电子产…

【Spring】 Spring中的IoC(控制反转)

以往在定义业务层实现时&#xff0c;在指定具体地Dao时候需要具体地定义出其实现&#xff1a; public class BookServiceImpl implements BookService{private BookDao bookDao new BookDaoImpl();public void save(){bookDao.save()} }public class BookDaoImpl implements …

什么是美国服务器,有哪些优势,适用于什么场景?

​  在互联网发展的过程中&#xff0c;服务器扮演着至关重要的角色。而美国作为全球信息技术的中心&#xff0c;其服务器在全球范围内受到广泛关注。  美国服务器是指在美国本土机房搭建并运行的服务器。其拥有带宽大、优质硬件、售后运维好、位置优越、数据安全性高以及免备…

命令行中引导用户指定选择文档

背景 在python中&#xff0c;我们如果需要操作文档&#xff0c;则需要用户指定文档&#xff0c;那么&#xff0c;如何引导用户指定或者选择文档呢&#xff1f; 导入包 本次我们即将演示的代码&#xff0c;使用了 DebugInfo python包&#xff0c;我们需要导入 DebugInfo 包 …

接口返回的二进制音频数据转url

const data await textToVoice({tts1: { input: "你好吗", speed: "1.0" }, });//data 接口返回的二进制音频数据 const blobData new Blob([data], { type: "audio/mpeg" }); const url window.URL.createObjectURL(blobData); // url >…

Flex布局---看一篇就够了

1. flex布局是什么&#xff1f; flex是flexible Box的缩写&#xff0c;用来为盒装模型提供的最大的灵活性&#xff0c;任何一个容器都可以指定为flex布局。Flex布局称为flex容器&#xff0c;所有的子元素为容器成员Flex项目&#xff08;flex item&#xff09;&#xff1b; 当为…

城市生命线丨城市燃气管网监测系统功能效果

11月6日&#xff0c;福建泉州某小区发生煤气闪爆导致1死三伤&#xff0c;这起事故再次为我们敲响了城市燃气管网安全监测的警钟。在城市生命线的建设中&#xff0c;城市燃气管网监测系统以其独特的作用和价值&#xff0c;成为保障城市安全的重要一环。 根据应急管理部《全国城镇…

zookeeper的安装部署

目录 简介 Zookeeper架构设计及原理 1.Zookeeper定义 2.Zookeeper的特点 3.Zookeeper的基本架构 4.Zookeeper的工作原理 5.Zookeeper的数据模型 &#xff08;1&#xff09;临时节点 &#xff08;2&#xff09;顺序节点 &#xff08;3&#xff09;观察机制 Zookeeper集…