当前位置: 首页 > news >正文

C++ vector

前言:

vector的部分源码:

(做过删除,留下关键信息)

 

vector的使用
 

构造函数:

1 无参构造
 

vector<int> v1;

 2 构造并初始化n个val

	vector<int> v2(5,1);

3 拷贝构造

 

	vector<int> v3(v2);

4 使用迭代器进行初始化构造 

迭代器可以是任意容器的迭代器

	vector<int> v3(v2.begin(), v2.end());

    string s("hello");vector<int> v3(s.begin(), s.end());

 

vector的 iterator 的使用
 

1 begin+end (顺序)

获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置的iterator/const_iterator

 

    string s("hello");vector<int> v2(s.begin(),s.end());vector<int>::iterator it = v2.begin();//auto it = v2.begin();while (it != v2.end()){cout << *it << " ";it++;}cout << endl;

 有迭代器,就可以使用范围for遍历数组

    for (auto e : v2){cout << e << " ";}cout << endl;

const对象使用const迭代器进行遍历打印:

    const vector<int> v(5,3);vector<int>::const_iterator it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;

 

 

2 rbegin+rend(逆序) 

获取最后一个数据位置的reverse_iterator/const_reverse_iterator,获取第一个数据前一个位置的
reverse_iterator/const_reverse_iterator

 

	string s("hello");vector<int> v2(s.begin(),s.end());vector<int>::reverse_iterator rit = v2.rbegin();//auto rit = v2.rbegin();while (rit != v2.rend()){cout << *rit << " ";rit++;}cout << endl;

 vector的容量空间

size:获取数据个数

capacity:获取容量大小

empty:判断是否为空

1 resize

改变vector的size

reisze(size_t n, const T& data = T())

n<size 删除作用

size<n<capacitty 插入作用

n>capacity 扩容+插入 

传参给val,就用传过来的值,若没有传参,则用缺省值:匿名对象(先调用构造完成初始化)拷贝构造val 

 可完成开空间+初始化

    vector<int> v;v.resize(4);

2 reserve 

改变vector的capacity

reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题
 

     vector<int> v;//v.reserve(100);size_t sz = v.capacity();for (size_t i = 0; i < 100; i++){v.push_back(i);if (sz != v.capacity()){sz = v.capacity();cout << "扩容:" << sz << endl;}}

使用reserve,没有发生扩容

    vector<int> v;v.reserve(100);size_t sz = v.capacity();for (size_t i = 0; i < 100; i++){v.push_back(i);if (sz != v.capacity()){sz = v.capacity();cout << "扩容:" << sz << endl;}}

 

 如果已经确定vector中要存储元素大概个数,可以提前将空间设置足够,就可以避免边插入边扩容导致效率低下的问题了


vector 增删查改


1 push_back(尾插)

2 pop_back(尾删)

    vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);vector<int>::iterator it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;v.pop_back();v.pop_back();it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;

3 find

 find不是vector自身提供的方法,是STL提供的算法,是算法模块实现,不是vector的成员接口

 4 insert

 在指定位置前插入值为val的元素,比如:3之前插入30,如果没有则不插入

5 erase 

 

    vector<int> v{ 1,2,3 ,4};// 使用列表方式初始化,C++11新语法vector<int>::iterator pos= find(v.begin(), v.end(), 3);//1. 先使用find查找3所在位置if (pos != v.end()){v.insert(pos, 20);// 2. 在pos位置之前插入30}auto it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;pos = find(v.begin(), v.end(), 3);v.erase(pos);it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;

insert和erase以后迭代器都失效了,不能在访问,所以以上代码中的迭代器pos在insert以后失效,重新赋值后,才可以使用

vector 迭代器失效问题

迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了封装,比如:vector的迭代器就是原生态指针T*

迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器,程序可能会崩溃)

迭代器失效解决办法:在使用前,对迭代器重新赋值即可
 

对于vector可能会导致其迭代器失效的操作有:


1. 会引起其底层空间改变的操作,都有可能使迭代器失效
 

比如:resize、reserve、insert、assign、push_back等

    vector<int> v{ 1,2,3,4,5,6 };auto it = v.begin();v.resize(100, 8);//扩容了,旧空间被释放掉//v.reserve(100)//扩容了//v.insert(v.begin(), 0);//扩容了//v.push_back(0);//扩容了//v.assign(100, 8);//扩容了while (it != v.end())//操作的是已经释放掉的旧空间,程序崩溃{cout << *it << " ";it++;}cout << endl;

程序崩溃原因:以上操作,都有可能会导致vector扩容,一旦扩容,vector底层原理旧空间被释放掉,而在打印时,it使用的是已经释放掉的旧空间,在对it迭代器操作时,实际操作的是一块已经被释放的空间,而引起代码运行时崩溃

解决方案:给it重新赋值即可
 

    vector<int> v{ 1,2,3,4,5,6 };auto it = v.begin();v.resize(100, 8);it = v.begin();//重新赋值while (it != v.end()){cout << *it << " ";it++;}cout << endl;

2. 指定位置元素的删除操作--erase
 

    vector<int> v{ 1,2,3,4,5,6 };auto pos = find(v.begin(), v.end(), 5);v.erase(pos); 删除pos位置的数据,导致pos迭代器失效cout << *pos << endl;//非法访问

erase删除pos位置元素后,pos位置之后的元素会全部往前移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了
 

下面来看实例:

删除vector中所有的偶数

错误代码:

   vector<int> v{ 1, 2, 3, 4 };auto it = v.begin();while (it != v.end()){if (*it % 2 == 0)v.erase(it);//erase以后,it迭代器失效++it;//报错}

正确代码:

	vector<int> v{ 1, 2, 3, 4 };auto it = v.begin();while (it != v.end()){if (*it % 2 == 0){it = v.erase(it);//it失效,重新赋值,it成为下一个要判断的数据的迭代器}else{it++;}}for (auto e : v){cout << e << " ";}cout << endl;

3 注意

Linux下,g++编译器对迭代器失效的检测并不是非常严格,处理也没有vs下极端

1. 扩容之后,迭代器已经失效了,程序虽然可以运行,但是运行结果已经不对了
2. erase删除任意位置代码后,linux下迭代器并没有失效,因为空间还是原来的空间,it的位置还是有效的

3 erase删除的迭代器如果是最后一个元素,it已经等于end,失效了,++it导致程序崩溃
4 与vector类似,string在插入+扩容操作+erase之后,迭代器也会失效
 


vector的遍历

1 operator[]

    vector<int> v{ 1,2,3,4 };for (size_t i = 0; i < v.size(); i++){v[i] *= 10;//写cout << v[i]<<" ";//读}



 2 迭代器遍历

    vector<int> v{ 1,2,3,4 };vector<int>::iterator it = v.begin();//auto it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;

 

3 范围for遍历 

    for (auto e : v){cout << e << " ";}cout << endl;

相关文章:

C++ vector

前言&#xff1a; vector的部分源码&#xff1a; &#xff08;做过删除&#xff0c;留下关键信息&#xff09; vector的使用 构造函数&#xff1a; 1 无参构造 vector<int> v1; 2 构造并初始化n个val vector<int> v2(5,1);3 拷贝构造 vector<int> v3…...

Spring+redis集成redis缓存

1、引入maven依赖 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.7.0</version></dependency><dependency><groupId>org.springframework.data</groupId><art…...

聊聊springboot的启动事件

序 本文主要研究一下springboot的启动事件 SpringApplicationEvent org/springframework/boot/context/event/SpringApplicationEvent.java public abstract class SpringApplicationEvent extends ApplicationEvent {private final String[] args;public SpringApplicatio…...

jmeter HTTP请求默认值

首先&#xff0c;打开JMeter并创建一个新的测试计划。 右键单击测试计划&#xff0c;选择"添加" > “配置元件” > “HTTP请求默认值”。 在HTTP请求默认值中&#xff0c;您可以设置全局的HTTP请求属性&#xff0c;例如&#xff1a; 服务器地址&#xff1a…...

CSS选择器-CSS3属性

CSS选择器-CSS3属性 持续更新… 1、CSS3的概念和优势 css3概念:是css的升级版本,新增加了一些模块 css3优点:完全向后兼容,可使用新的选择器和属性,能实现新的设计效果CSS3是CSS技术的升级版本&#xff0c;CSS3语言开发是朝着模块化发展的。以前的规范作为一个模块实在是太庞…...

线性代数的学习和整理8:行列式相关

目录 1 从2元一次方程组求解说起 1.1 直接用方程组消元法求解 1.2 有没有其他方法呢&#xff1f;有&#xff1a;比如2阶行列式方法 1.3 3阶行列式 2 行列式的定义 2.1 矩阵里的方阵 2.2 行列式定义&#xff1a;返回值为标量的一个函数 2.3 行列式的计算公式 2.4 克拉…...

java+springboot+mysql农业园区管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的农业园区管理系统&#xff0c;系统包含超级管理员、管理员、用户角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;管理员管理&#xff1b;用户管理&#xff1b;土地管理&#xff08;租赁&#xff09;&#x…...

IDEA远程开发

IDEA远程开发 前期准备 IDEA的远程开发是在本地去操昨远程服务器上的代码&#xff0c;所以我们先需要准备一台服务器,在此我使用vmware虚拟出ubuntu-20.04.6的Server版本,以便后面演示。 Ubuntu的Java环境配置 JDK8 sudo apt install openjdk-8-jdkmaven sudo apt instal…...

Redis 工作总结

1.Redis是什么 Redis是互联网技术领域使用最为广泛的存储中间件&#xff0c;它是Remote Dictionary Service的首字母缩写&#xff0c;也就是远程字典服务。 2.Redis的用途&#xff1f; 2.1 计数器 2.2 缓存 2.3 分布式锁 2.4 消息中间件 3.Redis的数据类型 3.1 string&am…...

GO学习之 数据库(Redis)

GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Htt…...

谈一谈浏览器与Node.js中的JavaScript事件循环,宏任务与微任务机制

JavaScript中的异步代码 JavaScript是一个单线程非阻塞的脚本语言。这代表代码是执行在一个主线程上面的。但是JavaScript中有很多耗时的异步操作&#xff0c;例如AJAX&#xff0c;setTimeout等等&#xff1b;也有很多事件&#xff0c;例如用户触发的点击事件&#xff0c;鼠标…...

User Java bean的命名规范

Java Bean 是一种用于表示简单的、可重用的组件的规范。它是一个符合特定命名和约定的 Java 类&#xff0c;通常用于封装数据和提供访问方法。以下是关于 Java Bean 命名规范的一些准则&#xff1a; 类名&#xff1a; 类名应该使用驼峰命名法&#xff08;Camel Case&#xff09…...

ajax和fetch的区别

ajax 和 fetch的相同点和区别是什么&#xff1f; 以前我们都用ajax去做请求&#xff0c; 但是原生的ajax不好用&#xff0c;我们会用$.ajax或者axios插件去请求&#xff0c;他们都是ajax的封装 最近出来个fetch是什么&#xff1f; 问到这里的时候&#xff0c;你就已经入坑了&am…...

java+springboot+mysql村务档案管理系统

项目介绍&#xff1a; 使用javaspringbootmysql开发的村务档案管理系统&#xff0c;系统包含超级管理员、工作人员角色&#xff0c;功能如下&#xff1a; 超级管理员&#xff1a;系统用户管理&#xff08;工作人员管理&#xff09;&#xff1b;公开资料&#xff1b;会议记录&…...

windows查看/删除DNS缓存

一、查看DNS缓存 打开CMD&#xff0c;输入ipconfig/displaydns 二、删除DNS缓存 打开CMD,输入ipconfig/flushdns...

自动化测试之Junit

Junit引入注解参数化单参数多参数方法传参 测试用例执行顺序断言测试套件 Junit引入 Junit来编写和组织自动化测试用例&#xff0c;使用Selenium来实际模拟用户与Web应用程序的交互。也就是使用JUnit的测试功能来管理和运行Selenium测试。常见的做法是&#xff0c;使用JUnit作…...

Spring Boot 整合MyBatis-Plus

&#x1f600;前言 本篇博文是关于Spring Boot 整合MyBatis-Plus的&#xff0c;希望你能够喜欢&#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的…...

CC++ 常用技巧

C 中的C C 是面向过程的是把整个大程序分为一个个的子函数&#xff1b;C 是面向对象的是把整个程序划分为一个个的类。C 是完全兼容C 的&#xff0c;C 是C 的子集&#xff0c;C 是C 的超集。C 又对C 做了很多补充和提升&#xff0c;因此使用C 会比使用纯C 更方便。混用C和C&am…...

【AndroidStudio】屏蔽小米打印

使用小米手机调试时&#xff0c;会一直有notifyQueue load error的打印 在过滤器重添加过滤条件即可 -message:notifyQueue...

Tomcat的安装与介绍

首先我们先了解一下什么是服务器&#xff1f;什么是服务器软件&#xff1f; 什么是服务器&#xff1f;安装了服务器软件的计算机。 什么是服务器软件&#xff1f; 服务器软件是一种运行在服务器操作系统上&#xff0c;用于接收和处理客户端请求&#xff0c;并提供相应服务和资…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...