C/C++STL学习[1]---顺序容器阐述、对比、选择vector,deque,list,forward_list,array,string

文章目录

  • 前言
  • 1. 顺序介绍
  • 2. 容器对比说明
  • 3. 容器选择
  • 总结

前言

STL系列博客开篇,记录一下自己学C++STL相关的心得。
这篇博客主要是写顺序容器的类型以及各个容器之间的异同还有平时对容器使用的选择。


1. 顺序介绍

顺序容器表示这个容器提供了快速顺序访问元素的能力。

下面是常用的一些顺序容器:

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

2. 容器对比说明

array与vector

array就是我们使用的数组。我们一般使用数组的时候都是这样定义的int a[10],这个表示我定义了一个存放int类型数据的数组,数组长度为10。但是我们存放数据的时候,数据会一直增加,很难确定应该给多大的容量才可以保证既不浪费内存又能够满足我们需求。

在我学STL之前,刷题的时候喜欢定义数组。比如要输入20个数据,我就给他定义个25个长度的数组。或者对于不可确定的长度,我往往定义很大的数组。这就导致内存总是过大,影响程序执行时间。

针对这种情况,STL中出现了vector。它解决了array的不可变长度问题。可以把它看成是一个可变长的数组。对于array的数据插入,如果新数据不在尾部插入的话,就意味着数据就要产生移动。比如长度为10的数组,我已存放4个数据,我现在想在第2个位置插入数据,这时候,后面的3,4位数据就要依次往后移动一个单位长度。如果数据量很大,这就导致插入效率很低。vector是array的变形,从定长转向不定长,但是由于存储方式的原因,它还是无法解决这种中途插入带来的效率低问题。但是由于是顺序插入,所以可以用下标的方式进行数据读取。这个就是它的优点:支持快速随机访问。


vector与string

string和vector都是将元素保存在连续的内存空间中。string是专门存放字符的一种vector容器(这是我自己理解的)。所以vector的特性string都有,比如快速随机访问,以及中间插入很慢,尾部插入或者删除很快。


list与forward_list
有前面的连续内存分配方式,就会有分散的内存分配方式。前者的优点是支持快速随机访问,后者就需要依次遍历。后者通常采用链表的方式进行数据存储。

list就是一个双端的链表。这说明list支持头插和尾插。这个和双端队列deque很相似。forward_list直译过来就是前端队列,这说明forward_list只支持从链表头进行插入数据。这两个容器的好处就是解决了上面array,vector,string三种容器插入删除中间元素过慢的问题,因为是链表存储,所以不涉及到依次移动元素。但是元素的访问必须要依次遍历每一个元素。


deque与其他容器
deque是一个双端队列,更加复杂一些。deque存放数据是连续内存分配的方式,所以和string,vector一样,支持快速随机访问。同样的,不可避免的就是中间插入或删除元素的代价可能很高。

但是在deque的两端添加或删除元素都是很快的,与list或forward_list添加删除元素的速度相当。

我个人理解是,deque是既想要有快速访问的效果,但是又想提高元素的插入删除的效率。但由于是内存的连续分配,所以不可避免插入的效率低,只能通过改变插入的位置来提高效率,就有了头尾插法。


3. 容器选择

没学STL之前嘛,那就是直接一个数组,顶多再来个链表搞定所有。学了之后,这么多种容器,怎么选?下面是一些参考意见。

通常使用了STL的话,vector是最好的选择。

  • 除非你有很好的理由选择其他容器,否则应使用vector。
  • 如果你的程序有很多小的元素,且空间的额外开销很重要,则不要使用list或forward_list。
  • 如果程序要求随机访问元素,应使用vector或deque。
  • 如果程序要求在容器的中间插入或删除元素,应使用list 或forward_list。·如果程序需要在头尾位置插入或删除元素,但不会在中间位置进行插入或删除操作,则使用deque。
  • 如果程序只有在读取输入时才需要在容器中间位置插入元素,随后需要随机访问元素,则
    首先,确定是否真的需要在容器中间位置添加元素。当处理输入数据时,通常可以很容易地向vector追加数据,然后再调用标准库的sort函数来重排容器中的元素,从而避免在中间位置添加元素。
    如果必须在中间位置插入元素,考虑在输入阶段使用list,一旦输入完成,将list中的内容拷贝到一个vector中。

如果程序既需要随机访问元素,又需要在容器中间位置插入元素,那该怎么办?答案取决于在list或forward_list中访问元素与vector或deque 中插入/删除元素的相对性能。一般来说,应用中占主导地位的操作(执行的访问操作更多还是插入/删除更多)决定了容器类型的选择。在此情况下,对两种容器分别测试应用的性能可能就是必要的了。
如果你不确定应该使用哪种容器,那么可以在程序中只使用vector和list

公共的操作:使用迭代器,不使用下标操作,避免随机访问。这样,在必要时选择使用vector或list都很方便。


总结

第一次看完之后还是有些笼统,写这篇博客的时候又复盘了一遍,印象更加深刻一些。

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

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

相关文章

【csdn默认使用操作详解】

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

芋道源码ruoyi-vue-pro项目前端yarn下载报错

安装了node最新的版本20.10.0,结果yarn下载依赖报错。 D:\code\IdeaProject\ruoyi-vue-pro\yudao-ui\yudao-ui-admin-vue2-master>yarn -install error achrinza/node-ipc9.2.2: The engine "node" is incompatible with this module. Expected versi…

使用PCSS实现的实时阴影效果

PCSS的技术可以使得阴影呈现出近硬远软的效果,并且能够实时实现。 其核心理念是通过模拟光源的面积来产生更自然、更柔和的阴影边缘。 具体步骤: 1、生成shadowmap 2、在进行阴影的比较时候进行平均,并非之前的shadow map 或者之后完全的阴影…

纯代码压缩WordPress前端Html

易于阅读的前端代码对开发而言是无比重要的,但对于浏览器来说就显得无比鸡肋了,毕竟浏览器不是像人眼一样看代码,过多的换行和空格,对前台加载是有一定影响的,对使用大带宽高配置服务器的网站,这么点影响可…

【Arduino库之:FastLED库】

FastLED 是一款功能强大,简单易用的控制WS2812, LPD8806, 等LED光带的Arduino第三方库。 第一:基础显示 led [ 0 ] CRGB::Red; //为第一个灯珠设置红色 FastLED.show(); //这个作用才会显示 示例程序: 此程序展示了FASTLED库控制WS2821…

YOLOv8创新魔改教程(二)如何添加注意力机制

YOLOv8创新魔改教程(二)如何添加注意力机制 (一)找代码 github找各种注意力机制的代码 (二)融合 1.创建文件 在ultralytics/nn/attention.py创建attention.py 文件 将找到的代码粘贴进来 2.修改task…

【计算机组成原理】存储器知识

目录 1、存储器分类 1.1、按存储介质分类 1.2、按存取方式分类 1.3、按信息的可改写性分类 1.4、按信息的可保存性分类 1.5、按功能和存取速度分类 2、存储器技术指标 2.1、存储容量 2.2、存取速度 3、存储系统层次结构 4、主存的基本结构 5、主存中数据的存放 5.…

prometheus|云原生|轻型日志收集系统loki+promtail的部署说明

一, 日志聚合的概念说明 日志------ 每一个程序,服务都应该有保留日志,日志的作用第一是记录程序运行的情况,在出错的时候能够记录错误情况,简单来说就是审计工作,例如nginx服务的日志,kuber…

分享一下docker的使用心得

好的,以下是一篇关于Docker使用心得的博客,希望能够帮助到大家。 Docker是一款开源的容器化平台,它可以让开发者将应用程序以及所有依赖项打包到一个可移植的容器中,然后将其部署到任何Docker环境中。Docker的使用可以带来很多好处…

SpringMVC的基础知识

SpringMVC的简介 MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分 M:Model,模型层,指工程中的JavaBean,作用是处理数据 JavaBean分为两类: 一类称为实体类Bean:专门存储业务数据的…

Java 使用html2image将html生成缩略图图片

POM文件添加Maven依赖 <dependency><groupId>gui.ava</groupId><artifactId>html2image</artifactId><version>0.9</version></dependency> 主要代码&#xff1a; String coverPath null;try {HtmlImageGenerator imageGene…

C++-模板

目录 一.泛型编程 二.模板的分类 三.函数模板 1.函数模板的概念 2.函数模板格式 3.函数模板的原理 4.函数模板的实例化 a.隐式实例化 b.显式实例化 5.模板参数的匹配原则 四.类模板 1.类模板的定义格式 2.类模板的实例化 五.class和typename的区别 六.非类型模板…

docker配置redis插件

docker配置redis插件 运行容器redis_6390 docker run -it \ --name redis_6390 \ --privileged \ -p 6390:6379 \ --network wn_docker_net \ --ip 172.18.12.19 \ --sysctl net.core.somaxconn1024 \ -e TIME_ZONE"Asia/Shanghai" -e TZ"Asia/Shanghai"…

【大连民族大学C语言CG题库练习题】——加密文件1

【问题描述】有一种加密方法为&#xff1a;其使用一个字母串&#xff08;可以含重复字母&#xff0c;字母个数不超过50&#xff09;作为密钥。假定密钥单词串为feather&#xff0c;则先去掉密钥单词中的重复字母得到单词串feathr&#xff0c;然后再将字母表中的其它字母以反序追…

Nacos源码解读04——服务发现

Nacos服务发现的方式 1.客户端获取 1.1:先是故障转移机制判断是否去本地文件中读取信息&#xff0c;读到则返回 1.2:再去本地服务列表读取信息(本地缓存)&#xff0c;没读到则创建一个空的服务&#xff0c;然后立刻去nacos中读取更新 1.3:读到了就返回&#xff0c;同时开启定时…

nginx优雅如何优雅的接管【跨域配置】

跨域问题太常见了&#xff0c;这里不做详细赘述。文章主要想说一下&#xff0c;如何统一管理和更好的来管理 跨域配置 跨域的常见配置有两种 后台代码设置和网关设置 1、后台代码设置 以springboot为例代码如下&#xff08;水一下文章长度...&#xff09; Configuration pu…

洛谷 P2935 [USACO09JAN] Best Spot S

文章目录 [USACO09JAN] 最佳牧场 S题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 思路解析CODE [USACO09JAN] 最佳牧场 S 题目链接&#xff1a;https://www.luogu.com.cn/problem/P2935 题目描述 贝茜&#xff0c;总是希望优化她的生活&#xff0c;她发现自己…

Linux下activemq的安装与安装成功确认

一、下载 apache-activemq-5.14.0-bin.tar.gz 二、安装 将压缩包拷入linux内&#xff0c;进行解压tar -zxvf apache-activemq-5.14.0-bin.tar.gz&#xff0c;与redis、nginx不同的是&#xff0c;active解压不需要安装就可以直接启动&#xff01; 启动命令&#xff1a;./bin…

1949-2021年全国31省公路里程数据

1949-2021年全国31省公路里程数据 1、指标&#xff1a;公路里程 2、范围&#xff1a;包括31省 1978-2021年期间无缺失 3、来源&#xff1a;各省NJ、产业NJ、各省统计GB 4、指标解释&#xff1a;公路里程指报告期末公路的实际长度。 统计范围&#xff1a;包括城间、城乡间、乡…

Rocketmq架构

NameServer&#xff1a;作为注册中心&#xff0c;提供路由注册、路由踢出、路由发现功能&#xff0c;舍弃强一致&#xff0c;保证高可用&#xff0c;集群中各个节点不会实时通讯&#xff0c;其中一个节点下线之后&#xff0c;会提供另外一个节点保证路由功能。 Rocket mq name…