vector讲解
在学习玩string后我们开始学习vector,本篇博客将对vector进行简单的介绍,还会对vector一些常用的函数进行讲解
vector的介绍
实际上vector就是一个数组的数据结构,但是vector是由C++编写而成的,他和数组也有本质上的区别,但也有相同点,他的特征概括如下:
- vector是表示可变大小数组的序列容器。
- 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
- 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
- vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
- 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
- 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list统一的迭代器和引用更好。
对于C语言中的数组,二者有很多的异同点,我将其概括如下:
相同点:
1 二者都是采用连续的空间来存储元素
2 二者都能通过下标进行访问
不同点:
1 vector是采用动态开辟,容器大小可以动态改变,并且是自动处理
2vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大
vector的使用
vector的定义
vector的定义就差不多是初始化以及拷贝构造和构造,这些在之前的string类函数讲解中也提到了,其实都大差不差的
构造并初始化:
第一个参数是你要初始化元素的个数,第二个参数是你要初始化成的字符
这里需要注意**<>里面就是你要放入vector里元素的类型**
vector<int> v(10, 1);
for (auto ch : v)
{cout << ch;
}
cout << endl;
拷贝构造:
其实都大差不差,学习了前面的string和类和对象后都很简单了
vector<int> v(10, 1);vector<int> v1(v);for (auto ch : v1){cout << ch;}cout << endl;
vector iterator 的使用
迭代器很常用,咱们做个简单的讲解
迭代器同样地分为正向和反向:
我们可以通过一个简单的代码来了解迭代器的使用
vector<int> v;
for (int i = 1; i <= 5; i++)
{v.push_back(i);
}
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{cout<< ' ' << *it;
}
cout << endl;
下面为反向迭代器:
反向迭代器记得加上reverse
vector<int> v;
for (int i = 1; i <= 5; i++)
{v.push_back(i);
}
for (vector<int>::reverse_iterator it = v.rbegin(); it != v.rend(); it++)
{cout<< ' ' << *it;
}
cout << endl;
关于begin和rbegin,end和rend的位置的关系如下图所示,我们要记得,两种迭代器都是从begin开始遍历:
通过这张图,我们需要注意到一个很重要的点:
迭代器的区间都是左闭右开的!所以end是在最后一个元素的后一个位置!
vector 空间增长问题
其实空间增长问题我在之前的string类就有提到过,都是有规律可循的:
1 capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。vector增容都是2倍,具体增长多少是根据具体的需求定义
2 reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
3 resize在开空间的同时还会进行初始化,影响size
可以看到,resize默认就是初始化为0:
同时改变了capacity和size
而reserve只改变了capacity,并且不会有初始化的功能:
vector<int> v;
v.reserve(10);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{cout<< ' ' << *it;
}
cout << endl;
cout << "former:" << endl;
cout << v.size() << endl;
cout << v.capacity() << endl;
v.reserve(20);
cout << endl;
cout << "after:" << endl;
cout << v.size() << endl;
cout << v.capacity() << endl;
vector 增删查改
pushback尾插和popback尾删:
都很简单,拿一段简单的代码来演示一下吧:
vector<int> v;
v.resize(10,1);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{cout<< ' ' << *it;
}
cout << endl;
v.push_back(2);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{cout << ' ' << *it;
}
cout << endl;
v.pop_back();
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{cout << ' ' << *it;
}
cout << endl;
insert插入函数:
这里如果需要在其他地方插入就在begin上进行+操作
vector<int> v;
v.resize(10,1);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{cout<< ' ' << *it;
}
cout << endl;
vector<int>::iterator it = v.begin();
v.insert(it, 3);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{cout << ' ' << *it;
}
cout << endl;
erase函数:
erase函数可以根据下标索引来删除元素,但是再insert后要重新给下标赋值,insert前的下标i已经失效了,其实这就是所说的:迭代器失效问题!
在这里我们插入了元素后会发生扩容,原空间可能已经被释放了(或者说如果erase删除了最后一个位置的元素,vector里已经没有元素可以删除,也会导致迭代器失效),但是erase后我们又使用it打印,这里的it可能使用的就是原空间,程序就会发生崩溃,所以我们需要在执行完insert后再次对it进行赋值,不然就会发生这种情况(但是一些编译器对于迭代器失效没有过于严格的检查,所以程序不会崩溃,但是程序输出的结果不对):
erase函数返回的是在vector对象中删除元素的后一个元素的指针!
通常解决迭代器失效最简单的方法就是:
对迭代器重新赋值
vector<int> v;
v.resize(10,1);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{cout<< ' ' << *it;
}
cout << endl;
vector<int>::iterator i = v.begin();
v.insert(i+3, 3);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{cout << ' ' << *it;
}
cout << endl;
i = v.begin();
v.erase(i+3);
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{cout << ' ' << *it;
}
cout << endl;
swap函数:
我们通过一段简单的代码来了解一下:
我们交换前打印两个vector对象中的元素,交换后再打印一次
vector<int> v1;
v1.resize(10,1);
cout << "交换前" << endl;
cout << "v1:";
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{cout<< ' ' << *it;
}
cout << endl;
vector<int> v2;
v2.resize(10, 2);
cout << "v2:";
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{cout << ' ' << *it;
}
cout << endl;
v1.swap(v2);
cout << "交换后" << endl;
cout << "v1:";
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{cout << ' ' << *it;
}
cout << endl;
cout << "v2:";
for (vector<int>::iterator it = v2.begin(); it != v2.end(); it++)
{cout << ' ' << *it;
}
cout << endl;
好了,今天的分享到这里就结束了,谢谢大家的支持!
相关文章:

vector讲解
在学习玩string后我们开始学习vector,本篇博客将对vector进行简单的介绍,还会对vector一些常用的函数进行讲解 vector的介绍 实际上vector就是一个数组的数据结构,但是vector是由C编写而成的,他和数组也有本质上的区别ÿ…...

nvm 配置淘宝镜像失效,以及安装node后 npm-v 无效
win11 nvm版本 1.1.4 和1.1.7和1.1.12(目前最新版本24年 一月二十三日) 以上nvm版本都会出现一下问题, 从https://github.com/coreybutler/nvm-windows/releases 下载nvm安装包如下图 傻瓜式安装后,不用去配置环境变量&#…...

【Android Gradle 插件】Gradle 基础配置 ④ ( Gradle Wrapper 配置作用 | Gradle 下载的依赖库存放位置 )
一、Gradle Wrapper 配置作用 gradle wrapperdistributionBaseGRADLE_USER_HOME distributionPathwrapper/dists distributionUrlhttps\://services.gradle.org/distributions/gradle-6.7.1-bin.zip zipStoreBaseGRADLE_USER_HOME zipStorePathwrapper/distsGradle Wrapper 配…...

Deepin_Ubuntu_查看树形目录结构(tree)
Linux系统(Deepin、Ubuntu)中,可以使用tree命令来查看树形目录结构,下面是一些示例: 查看当前目录的树形结构: tree查看指定目录的树形结构,例如/etc/X11/fonts目录: tree /etc/X…...
Java Excel分割成许多小文件
最近在处理excel,数据很多,需要将excel拆分成许多小块,并保留原来的格式,于是写了该算法,并能保留原来的样式,使用很简单: Sheet splitSheet ExcelUtil.split(sheet, 0, 20, 5, 8); 传入开始…...

【心得】java从CC1链入门CC链个人笔记
来劲了,感觉离真正的CTF又近了一步。 本文仅从一个萌新的角度去谈,如有纰漏,纯属蒟蒻。 目录 CC链概念 CC链学习前置知识 CC1链 Version1 Version2 Version3 CC链概念 CC链 Commons Collections apache组织发布的开源库 里面主要对…...
Django migration 新增外键的坑
TL;DR 永远不要相信 makemigrations! migrate 之前一定好好看看 migrate 了啥东西,必要时手动修改生成的 migrate 文件。 最好把db的更新与服务代码更新解耦 场景 先描述下场景: 现在有两个表,一个是 question,一…...

相关系数(皮尔逊相关系数和斯皮尔曼相关系数)
本文借鉴了数学建模清风老师的课件与思路,可以点击查看链接查看清风老师视频讲解:5.1 对数据进行描述性统计以及皮尔逊相关系数的计算方法_哔哩哔哩_bilibili 注:直接先看 ( 三、两个相关系数系数的比较 ) 部分&#x…...
了解 Vite 插件
众所周知 Vite 是基于 Rollup 的构建工具,Vite 插件为了优化、扩展项目构建系统功能的工具。 比如 vite-plugin-eslint 为我们提供了代码分析的功能,帮助我们在开发过程中的风格一致性。 简单示例 本文中的示例是基于 Vite Vue3.x TypeScript 来实现…...
算法竞赛基础:C++双向链表的结构和实现(普通链表、List、静态链表)
算法竞赛基础:双向链表 本文将会介绍在算法竞赛中双向链表的几种使用方式,适合有一定基础的人阅读。 双向链表的结构 一般来说,普通的链表结构是这样的: struct node {int num;node *next; }next指针指向下一个链表ÿ…...
openssl3.2/test/certs - 019 - ca-nonca trust variants: +serverAuth, +anyEKU
文章目录 openssl3.2/test/certs - 019 - ca-nonca trust variants: serverAuth, anyEKU概述笔记 ca-nonca.pem from exp 016openssl3.2/test/certs - 019 - ca-nonca trust variants: serverAuth, anyEKUEND openssl3.2/test/certs - 019 - ca-nonca trust variants: serverAu…...

Unity SRP 管线【第五讲:URP烘培光照】
本节,我们将跟随数据流向讲解UEP管线中的烘培光照。 文章目录 一、URP烘培光照1. 搭建场景2. 烘培光照参数设置MixedLight光照设置:直观感受 Lightmapping Settings参数设置: 3. 我们如何记录次表面光源颜色首先我们提取出相关URP代码&#…...

Mysql运维篇(一) 日志类型
一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人,如有侵权请留言,我及时删除。 一、mysql相关日志 首先,我们能接触到的,一般我们排查慢查询时,会去看慢查询日志。如果做过数据备份会恢复的,可能接触或用过BinLog。那还有其他的吗?对MySQL原理…...
【C语言】结构体与内存操作函数 总结
结构体 一、结构体简介 C 语言内置的数据类型,除了最基本的几种原始类型,只有数组属于复合类型,可以同时包含多个值,但是只能包含相同类型的数据,实际使用中并不够用。 实际使用中,主要有下面两种情况&a…...

第12章_集合框架(Collection接口,Iterator接口,List,Set,Map,Collections工具类)
文章目录 第12章_集合框架本章专题与脉络1. 集合框架概述1.1 生活中的容器1.2 数组的特点与弊端1.3 Java集合框架体系1.4 集合的使用场景 2. Collection接口及方法2.1 添加2.2 判断2.3 删除2.4 其它 3. Iterator(迭代器)接口3.1 Iterator接口3.2 迭代器的执行原理3.3 foreach循…...

C语言进阶——数据结构之链表(续)
前言 hello,大家好呀,我是Humble,本篇博客承接之前的C语言进阶——数据结构之链表 的内容(没看过的小伙伴可以从我创建的专栏C语言进阶之数据结构 找到那篇文章并阅读后在回来哦~),上次我们重点说了链表中…...

数据库课程设计-图书管理系统数据库设计
目录 一、实验目的 二、实验内容 三、实验要求 四、实验设计 4.1需求分析 4.1.1系统目标 4.1.2功能需求 4.1.3性能需求 4.14界面需求 4.2概念模型设计 4.2.1 实体及联系 4.2.2 E-R图 4.3 逻辑设计 4.3.1 E-R模型向关系模型的转换 4.3.2 数据库逻辑结构 4.3.3数据库模型函数依赖…...

【超简版,代码可用!】【0基础Python爬虫入门——下载歌曲/视频】
安装第三方模块— requests 完成图片操作后输入:pip install requests 科普: get:公开数据 post:加密 ,个人信息 进入某音乐网页,打开开发者工具F12 选择网络,再选择—>媒体——>获取URL【先完成刷新页面】 科…...
CommunityToolkit.Mvvm支持环境
引言 CommunityToolkit.Mvvm 包(又名 MVVM 工具包,以前称为 Microsoft.Toolkit.Mvvm)是一个现代、快速和模块化的 MVVM 库。 它是 .NET 社区工具包的一部分,其中一条原则是: 独立于平台和运行时 - .NET Standard 2.0…...

探讨品牌设计的本质,为企业形象注入活力!
品牌设计作为一个行业,首先需要明确行业的本质和意义。由于越来越多的咨询公司和营销公司对品牌有不同的理解和解释,因为他们服务的内容和专业水平不同,什么是品牌的定义越来越复杂,逐渐成为一种神秘的知识。例如,特劳…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...