C++:Vector的使用
一、vector的介绍
vector的文档介绍
1. vector是表示可变大小数组的序列容器。
2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
6. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起listforward_list统一的迭代器和引用更好。
下面我们开始研究他的使用,为了能够更好的测试,我们先实现一个打印容器元素的函数,vector底层是数组,所以有三种访问方式:下标访问、迭代器访问、范围for(本质也是迭代器)
void Print(const vector<int>& vv)//专门用来打印函数
{//下标遍历for (size_t i = 0; i < vv.size(); ++i)cout << vv[i] << " ";cout << endl;//迭代器区间访问vector<int>::const_iterator it = vv.begin();while (it != vv.end()){cout << *it << " ";++it;}cout << endl;//范围for访问for (auto e : vv)cout << e << " ";cout << endl;
}
二. 构造和赋值重载(Member functions)


我们用test1()来展示用法
void test1()
{//无参构造vector<int> v1;Print(v1);//有参构造,n个位置初始化vector<int> v2(5,2);Print(v2);//有参构造,n个位置调用T类型的默认构造vector<int> v3(5);Print(v3);//拷贝构造vector<int> v4(v3);Print(v4);//迭代器区间构造(传string的迭代器区间)string s("hello world");vector<int> v5(s.begin(), s.end());Print(v5);//迭代器区间构造(传vctor的迭代器区间)vector<int> v6(v5.begin(), v5.end());Print(v6);//赋值重载v1 = v6;cout << &v1 <<" "<< & v6 << endl;//深拷贝Print(v1);//特殊的赋值方式vector<int> v7{ 1,2,3,4,5,6,7,8 };Print(v7);
}

注意:如上图所说,虽然构造函数的本质是为了自定义类型而生的,但是因为有了模版的存在,在有些时候必须支持内置类型的默认构造,比如我们来看下面的测试
//有些必要的时候必须得有拷贝构造
template<class T>
void func()
{T x = T();cout << x << endl;
}
void test4()
{//有模板的时候必须有内置类型的默认构造func<int>();func<int*>();func<double>();func<float>();
}
除了指针以外的内置类型也可以直接进行默认构造

三、增删操作(Modifiers Iterators)
我们先介绍再测试

原有的空间会全部清空,替换成我们要插入的元素,如果插入的更大,会扩容到相应的大小,跟=很相似,因为都会造成原来空间的释放,但是assign有一个比较厉害的地方就是可以用迭代器,也就是说我们可以控制被替换的区间

尾插

尾删

指定位置插入,要注意的是这里不再像string一样,用的size_t 的pos,vector虽然也可以用下标访问,但是为了承接后面STL其他不支持下标访问的容器,所以这边的pos用的是迭代器类型
指定位置删除

交换两个容器的指针,其实只是交换了空间,跟全局的swap区别就是全局的swap还涉及到了开空间和拷贝

很简单,就是清空容器,但是是不会改变容量的!
下面我们用test2()来进行测试
void test2()
{vector<int> v1;//push_backv1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.push_back(6);v1.push_back(7);v1.push_back(8);Print(v1);//pop_backv1.pop_back();Print(v1);//insertvector<int>::iterator pos1 = find(v1.begin(), v1.end(),2);v1.insert(pos1, 10);Print(v1);//erasevector<int>::iterator pos2 = find(v1.begin(), v1.end(), 10);v1.erase(pos2);Print(v1);//swap(vector 的swap)vector<int> v2(40,2);cout << &v1 << " " << &v2<<endl;v2.swap(v1);cout << &v1 << " " << &v2<<endl;Print(v1);Print(v2);//swap(全局的swap)swap(v1, v2);cout << &v1 << " " << &v2 << endl;Print(v1);Print(v2);//assign和=的区别 都会销毁源空间,但是assign可以用迭代器控制被赋值的范围 或者是自己指定替换n个相同元素v1.assign(10, 2);//强行替换了Print(v1);v1.assign(v2.begin()+5,v2.end()-1);//控制赋值返回Print(v1);v2 = v1;Print(v2);//clearv1.clear();Print(v1);//v1被清空了}

注意:Vector里面并没有提供find,但是算法库里有一个find是迭代器区间版本,也就是说算法库里的find支持给STL所有容器使用,所以才没有必要单独写一个!!
四、容量相关操作(Capacity)

这里和之前string的没什么差异,我们直接开始用test3进行测试
//Capacity
void test3()
{vector<int> v1{ 1,2,3,4,5,6,7,8,9,10};cout << v1.size() << endl;cout << v1.max_size() << endl;cout << v1.capacity() << endl;//reservev1.reserve(15);cout << v1.capacity() << endl;//resize //不传参数,调用默认构造v1.resize(50);Print(v1);//emptycout << v1.empty() << endl;//shrink_to_fitv1.reserve(100);cout << v1.capacity() << endl;v1.shrink_to_fit();cout << v1.capacity() << endl;
}

五、sort和reverse
这两个函数都是算法库里提供的,需要我们传相应的迭代器,但是内部使用是对迭代器有要求的,迭代器功能分为3种,一种是单向(比如单链表),一种是双向(双向链表),一种是随机(Vector和String),支持随机迭代器的一般都是支持下标访问的,名字会按时你要传什么样的迭代器。比如sort,一般只支持随机迭代器,而reverse一般支持双向迭代器,但是随机迭代器也是可以的,也就是说他们之间的关系是:单向支持双向和随机,双向支持随机,随机谁也不能支持
我们下面用test5()来测试一下
void test5()
{vector<int> v1{3,4,10,11,31,43,5464,4242432,22,3213};Print(v1);//升序sort(v1.begin(), v1.end(),less<int>());Print(v1);//逆序sort(v1.begin(), v1.end(), greater<int>());reverse(v1.begin() + 2, v1.end() - 5);Print(v1);
}

测试用例都给大家了,大家可以自己用vs拷贝过去哦!下一章开始讲解Vector的模拟实现
思考:有了Vector(char)还需要string吗?
需要!!1、如果用Vector(char)那其实底层又回到C语言的字符数组概念了,我们封装string的原因就是字符数组不符合面向对象的思维。2、Vector(char)结尾不会带\0 3、Vector的实现是可以存储很多种类型,比较大小也是根据具体类型的比较方式去比较,而string都是根据ascii码去比较。4、+=的差别很大,string+=一个字符串很正常,但是Vector就不适合。5、字符串string支持找子串。
综上来说 string是需求专用,vector是无法满足string的所有接口需求的。

相关文章:
C++:Vector的使用
一、vector的介绍 vector的文档介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以…...
Redis之事务(详细解析)
请直接看原文:不能回滚的Redis事务还能用吗 - 知乎 (zhihu.com) ------------------------------------------------------------------------------------------------------------------------------ 1、Redis事务的概念: Redis 事务的本质是一组命令的集合。…...
Java项目:39 springboot007大学生租房平台的设计与实现
作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统有管理员、房东和用户 【主要功能】 1、后台:房源管理、信息审批管理、订单信息管理、房东管理、用户管理 2、前台࿱…...
安卓内存信息查看
目录 前言一、Android查看内存相关信息的方法1.1 通过 adb shell 获取内存信息1.2 通过编程方式获取内存信息1.3 adb shell 获取应用程序内存使用情况1.4 free指令 二、总结 前言 一、Android查看内存相关信息的方法 1.1 通过 adb shell 获取内存信息 C:\Users\henry.xue>…...
Positional Encoding 位置编码
Positional Encoding 位置编码 flyfish Transformer模型没有使用循环神经网络,无法从序列中学习到位置信息,并且它是并行结构,不是按位置来处理序列的,所以为输入序列加入了位置编码,将每个词的位置加入到了词向量中…...
MySql、Navicat 软件安装 + Navicat简单操作(建数据库,表)
一、MySql、Navicat 软件安装 及正常使用 MySql下载+安装: 检查安装情况: 配置环境变量: 搞定了!!! 可以登陆试哈哈哈 连接navicat 开始创建数据库 二、 商品种类表 - commoditytype int …...
逆向案例五、爬取b站评论,表单MD5加密
1.便捷写爬虫网站: Convert curl commands to code 使用流程:又点击想要抓的包,复制URL(base)格式复制 在上面链接中粘贴即可 2.找到含有评论的包(即main?oid):观察表单发现两处参数在变化&…...
010-原型链
原型链 1、概念2、原理3、new 操作符原理4、应用 1、概念 原型链:javascript的继承机制,是指获取JavaScript对象的属性会顺着其_proto_的指向寻找,直至找到Object.prototype上。 2、原理 💡 Tips:构造函数 Fn&#…...
Electron-builder打包安装包——编译篇
突然有一天想打包个桌面程序,没有打包过,经过九牛二虎之力终于打包出来,在此感谢那些热于分享的前辈! 本篇只讲打包运行和出现的问题 一、准备工作:提前下载相关资源包,否则在国内环境下可能因为网络问题…...
Red Hat系统升级内核版本
查看当前内核版本 uneme -r yum list kernel升级内核 yum update -y kernel检查升级后的内核版本 uneme -r yum list kernel升级系统中已安装的软件包到最新版本(过程时间较长) 目前只升级了系统内核,系统相关的安装包还是老的࿰…...
Java集合set之HashSet、LinkedHashSet、TreeSet的区别?
Java的集合中主要由List,Set,Queue,Map构成,Set特点:存取无序,不可以存放重复的元素,不可以用下标对元素进行操作。 HashSet 作为Set容器的代表子类,HashSet经常被用到,…...
全方位碾压chatGPT4的全球最强模型Claude 3发布!速通指南在此!保姆级教学拿脚都能学会!
🎉🎉欢迎光临,终于等到你啦🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏《Spring 狂野之旅:从入门到入魔》 &a…...
upload-Labs靶场“11-15”关通关教程
君衍. 一、第十一关 %00截断GET上传1、源码分析2、%00截断GET上传 二、第十二关 %00截断POST上传1、源码分析2、%00截断POST上传 三、第十三关 文件头检测绕过1、源码分析2、文件头检测绕过 四、第十四关 图片检测绕过上传1、源码分析2、图片马绕过上传 五、第十五关 图片检测绕…...
linux-rpm命令
rpm命令管理程序包:安装、升级、卸载、查询和校验 1、忽略依赖关系安装/卸载包 安装:rpm -Uvh 软件包名 --nodeps 卸载:rpm -e 软件包名 --nodes!!!!慎用!!!…...
如何利用python实现自己的modbus-tcp库
如果你想使用纯Socket编程来实现Modbus TCP通讯,而不是依赖于Modbus库,你需要理解Modbus TCP协议的细节,并能够手动构建和解析Modbus消息。以下是一个简单的示例,展示了如何使用Python的socket库来实现Modbus TCP通讯: 了解Modbus TCP协议: Modbus TCP协议使用TCP作为底层…...
linux系统-----------搭建LNMP 架构
PHP(Hypertext Preprocessor 超文本预处理器)是通用服务器端脚本编程语言,主要用于web开发实现动态web页面,也是最早实现将脚本嵌入HTML源码文档中的服务器端脚本语言之一。同时,php还提供了一个命令行接口,因此,其也可…...
C++中boost库的安装及使用(Windows)
Boost库的安装及使用 引言使用现有的boost库安装及使用引言 C++开发中经常会用到boost库,本文记录一下Windows上boost在visual studio2019上的使用。 Boost库是一个跨平台的C++库集合,旨在为C++开发者提供一系列高质量的通用功能。不同的Visual Studio(VS)版本并不要求安…...
CPP编程-CPP11中的内存管理策略模型与名称空间管理探幽(时隔一年,再谈C++抽象内存模型)
CPP编程-CPP11中的内存管理策略模型与名称空间管理探幽 CPP的四大内存分区模型 在 C 中,**内存分区是一种模型,用于描述程序运行时内存的逻辑组织方式,但在底层操作系统中,并不存在严格意义上的内存分区。**操作系统通常将内存分…...
springboot项目整合minio实现文件的分布式存储
minio是一款分布式存储系统,上一篇详细介绍了minio在windows环境下的搭建集群并通过nginx实现负载均衡,这里简单介绍下springboot项目整合minio并实现文件的上传下载删除等操作。 一、依赖的引入 1.1、maven项目 <dependency><groupId>io…...
微信小程序开发学习笔记《19》uni-app框架-配置小程序分包与轮播图跳转
微信小程序开发学习笔记《19》uni-app框架-配置小程序分包与轮播图跳转 博主正在学习微信小程序开发,希望记录自己学习过程同时与广大网友共同学习讨论。建议仔细阅读uni-app对应官方文档 一、配置小程序分包 分包可以减少小程序首次启动时的加载时间 为此&#…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
边缘计算网关提升水产养殖尾水处理的远程运维效率
一、项目背景 随着水产养殖行业的快速发展,养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下,而且难以实现精准监控和管理。为了提升尾水处理的效果和效率,同时降低人力成本,某大型水产养殖企业决定…...
深度解析云存储:概念、架构与应用实践
在数据爆炸式增长的时代,传统本地存储因容量限制、管理复杂等问题,已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性,成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理,云存储正重塑数据存储与…...

