【C++初阶】第11课—vector

文章目录

  • 1. 认识vector
  • 2. vector的遍历
  • 3. vector的构造
  • 4. vector常用的接口
  • 5. vector的容量
  • 6. vector的元素访问
  • 7. vector的修改
  • 8. vector<vector\<int\>>的使用
  • 9. vector的使用
  • 10. 模拟实现vector
  • 11. 迭代器失效
    • 11.1 insert插入数据内部迭代器失效
    • 11.2 insert插入数据外部迭代器失效
    • 11.3 erase删除数据迭代器失效
  • 12. 模拟实现resize
  • 13. 模拟实现vector的拷贝构造
  • 14. 模拟实现vector的赋值操作符重载
  • 15. 模拟实现reserve存在的坑
  • 16. 模拟实现vector初始化
  • 17. vector构造时容易出现的坑
  • 18. 模拟实现vector代码

1. 认识vector

  • vector是向量、矢量的意思
  • vector其实就是数据结构阶段学过的顺序表,行为看起来像指针一样的容器,底层不一定是用指针实现的,具体根据编译器的底层实现结构为准
  • vector的使用:vector<数据类型> 对象名

在这里插入图片描述


2. vector的遍历

在这里插入图片描述


3. vector的构造

在这里插入图片描述


  • 对于vector的析构,跟string类似,它会自动调用

4. vector常用的接口

在这里插入图片描述


  • vector上述的接口与string的接口并无二异

在这里插入图片描述


  • cbegin( )和cend( )的用法与begin和end类似,无非就是常量迭代器不能改变数据而已

5. vector的容量

在这里插入图片描述


在这里插入图片描述


  • 对于判空empty和请求缩容shrink_to_fit不再过多赘述,string里面都有讲到

6. vector的元素访问

在这里插入图片描述


在这里插入图片描述


  • at和下标访问操作符[ ]都是用来访问vector内的元素,区别是越界时下标操作符[ ]会报错,而at会抛出异常,关于这点string已经讲过,后续讲到捕获异常时可重温复习以加深理解

7. vector的修改

在这里插入图片描述


在这里插入图片描述


  • 其余的像swap用来交换两个vector对象,使用时可参考官方文档,大部分与string类模版中的用法类似

8. vector<vector<int>>的使用

  • vector<vector<int>>其实就是类似二维数组的用法,使用vector实例化出int类型的对象,再使用vector<vector<int>>实例化出vector<int>的对象

在这里插入图片描述


在这里插入图片描述


#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
//vector<vector<int>>的使用(杨辉三角)
size_t numRows = 0;
cin >> numRows; //行数
vector<vector<int>> vv(numRows);
//所有数设置为1
for (size_t i = 0; i < numRows; i++)
{vv[i].resize(i + 1, 1);
}
//中间元素为上面两个元素之和
for (size_t i = 2; i < numRows; i++)
{for (size_t j = 1; j < vv[i].size() - 1; j++){vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];}
}
//打印
for (size_t i = 0; i < numRows; i++)
{//打印前面的空格for (size_t k = 0; k < numRows - i - 1; k++){cout << " ";}for (size_t j = 0; j < vv[i].size(); j++){cout << vv[i][j] << " ";}cout << endl;
}
return 0;
}

9. vector的使用

  • 对于vector容器,也可以使用string类型,其插入string类型的数据如下

在这里插入图片描述


  • 关于vector和C++算法库的一些使用,以下先作为一个了解

在这里插入图片描述


10. 模拟实现vector

  • 之前讲述过,迭代器都是左闭右开的区间,对于begin指向第一个数,而end则指向最后一个数的下个位置
  • 因此对于vector的成员变量_start和_finish、_end_of_storage来讲,_finish就是指向有效数据的下个位置,_end_of_storage就指向容量的下个位置

在这里插入图片描述


在这里插入图片描述


  • 接下主要讲reserve扩容的坑,其余较容易实现

在这里插入图片描述


  • insert在pos位置插入字符
  • 注意:pos的类型是迭代器iterator,因为vector的成员变量是iterator类型,类似迭代器begin()和end()

在这里插入图片描述


  • 对于上述insert插入数据的代码,存在一个巨大隐患:迭代器失效的问题,接下来主要讲容器中的迭代器失效的问题

11. 迭代器失效

11.1 insert插入数据内部迭代器失效

在这里插入图片描述


  • 解决上面迭代器失效的方法:扩容后更新pos

在这里插入图片描述


11.2 insert插入数据外部迭代器失效

在这里插入图片描述


  • 即使是库里面实现的vector,对于insert插入数据也会出现迭代器失效的问题
  • 迭代器失效的根本原因就是扩容,扩容前后外部迭代器指向的是旧空间,而扩容后旧空间被释放,再访问就会报错
  • 因此对于insert插入数据后外部传参的迭代器,由于不同的平台结果可能不同,统一认为该迭代器失效
  • 解决办法:insert插入数据后更新迭代器

在这里插入图片描述


11.3 erase删除数据迭代器失效

在这里插入图片描述


在这里插入图片描述


  • 解决办法:在erase删除数据后即使更新迭代器it

在这里插入图片描述


  • 总结
  • 对于迭代器失效的问题,主要存在于容器插入和删除元素时,这里以vector为例,在insert插入数据和erase删除数据后,迭代器就处于失效的状态,这是因为插入数据扩容导致以及删除数据缩容导致的一系列问题
  • 对于不同的编译器,结果可能不同,并且vs对于迭代器失效的检查尤为严格,它会对失效的迭代器进行标记,如果尝试使用这些失效的迭代器,它就会报错
  • 因此统一认为容器插入数据和删除数据后迭代器处于失效的状态
  • 如果想继续使用失效的迭代器,解决办法就是在插入数据或删除数据前后根据实际情况及时更新迭代器,使迭代器正确指向对应的数据

12. 模拟实现resize

在这里插入图片描述


在这里插入图片描述


13. 模拟实现vector的拷贝构造

在这里插入图片描述


14. 模拟实现vector的赋值操作符重载

在这里插入图片描述


15. 模拟实现reserve存在的坑

  • reserve扩容的第一个坑

在这里插入图片描述


  • reserve扩容的第二个坑

在这里插入图片描述

  • 插入前四个字符串时没有问题,但是插入第5个字符串时,为什么会出现问题呢?
  • 因为插入第5个字符串时会扩容,reserve扩容中的memcpy其实就是一个浅拷贝,之前再C语言阶段实现过memcpy这个函数,它是一个字节一个字节拷贝的
  • 参考链接:memcpy的使用和模拟实现

在这里插入图片描述


在这里插入图片描述


  • 解决方案

在这里插入图片描述


16. 模拟实现vector初始化

  • C++11提供了vector初始化列表来进行初始化

在这里插入图片描述


  • inltializer_list是C++11设置一个模版类型
  • 其用法和之前创建数组有点类似

在这里插入图片描述


在这里插入图片描述


  • C++还提供了迭代器区间初始化

在这里插入图片描述


在这里插入图片描述


  • 当然数组也可以当做迭代器使用

在这里插入图片描述


17. vector构造时容易出现的坑

  • 用n个val值构造vector对象

在这里插入图片描述


在这里插入图片描述


  • 解决措施

在这里插入图片描述


18. 模拟实现vector代码

//模版
template <class T>
class vector
{
public://迭代器typedef T* iterator;typedef const T* const_iterator;//构造函数vector(){}//初始化列表初始化vector(initializer_list<T> il){reserve(il.size());for (auto& e : il){push_back(e);}cout << "初始化列表初始化:" << endl;}//迭代器区间初始化//类模板函数的成员函数,也可以是函数模版template <class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}//vector的构造--->n个valvector(int n, const T& val = T()){resize(n, val);}vector(size_t n, const T& val = T()){resize(n, val);}//拷贝构造 vector(const vector<T>& v){reserve(v.size());for (auto& e : v){//this->push_back(e);push_back(e);}}//有效数据sizesize_t size() const{return _finish - _start;}//容量size_t capacity() const{return _end_of_storage - _start;}//beginiterator begin(){return _start;}//enditerator end(){return _finish;}//const beginconst_iterator begin() const{return _start;}//const endconst_iterator end() const{return _finish;}//resize改变有效数据个数void resize(size_t n, const T& val = T()){if (n < size()){_finish = _start + n;}else{reserve(n);while (_finish != _start + n){*_finish = val;_finish++;}}}//扩容void reserve(size_t n){if (n > capacity()){size_t oldsize = size();T* tmp = new T[n];/*memcpy(tmp, _start, sizeof(T) * size());*/for (size_t i = 0; i < oldsize; i++){tmp[i] = _start[i];}delete[] _start;_start = tmp;_finish = oldsize + _start;_end_of_storage = n + _start;}}//尾插void push_back(const T& x){if (_finish == _end_of_storage){reserve(capacity() == 0 ? 4 : 2 * capacity());}*_finish = x;_finish++;}//尾删void pop_back(){assert(_finish > _start);_finish--;}//重载下标操作符[]T& operator[](size_t i){return _start[i];}//赋值操作符---第一种写法//vector<T>& operator=(const vector<T>& v)//{//	if (this != &v)//	{//		delete[] _start;//		_start = _finish = _end_of_storage = nullptr;//		reserve(v.size());//		for (auto& e : v)//		{//			//this->push_back(e);//			push_back(e);//		}//	}//	return *this;//}void swap(vector<T> v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_end_of_storage, v._end_of_storage);}//赋值操作符---第二种写法vector<T>& operator=(const vector<T>& v){swap(v);return *this;}//任意位置插入,insert插入数据后迭代器失效void insert(iterator pos, const T& x){assert(pos >= _start);assert(pos <= _finish);//满了扩容if (_finish == _end_of_storage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : 2 * capacity());pos = _start + len;}//挪动数据iterator end = _finish - 1;while (end >= pos){*(end + 1) = *end;--end;}//插入数据*pos = x;++_finish;}//erase删除数据iterator erase(iterator pos){assert(pos >= _start);assert(pos < _finish);iterator begin = pos + 1;while (begin < _finish){*(begin - 1) = *begin;++begin;}--_finish;return pos;}//析构~vector(){delete[] _start;_start = _finish = _end_of_storage = nullptr;}
private:iterator _start = nullptr;iterator _finish = nullptr;iterator _end_of_storage = nullptr;
};

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

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

相关文章

Linux查看服务器的内外网地址

目录&#xff1a; 1、内网地址2、外网地址3、ping时显示地址与真实不一致 1、内网地址 ifconfig2、外网地址 curl ifconfig.me3、ping时显示地址与真实不一致 原因是dns缓存导致的&#xff0c;ping这种方法也是不准确的&#xff0c;有弊端不建议使用&#xff0c;只适用于测试…

PAT甲级-1024 Palindromic Number

题目 题目大意 一个非回文数&#xff0c;加上它的翻转数所得的和&#xff0c;进行k次&#xff0c;有可能会得到一个回文数。给出一个数n&#xff0c;限制相加次数为k次&#xff0c;如果小于k次就得到回文数&#xff0c;那么输出该回文数和相加的次数&#xff1b;如果进行k次还…

xss靶场

xss-labs下载地址&#xff1a;GitHub - do0dl3/xss-labs: xss 跨站漏洞平台 xss常见触发标签&#xff1a;XSS跨站脚本攻击实例与防御策略-CSDN博客 level-1 首先查看网页的源代码发现get传参的name的值test插入了html里头&#xff0c;还回显了payload的长度。 <!DOCTYPE …

数据结构——实验七·排序

欢迎各位大佬们来到Tubishu的博客&#x1f31f; Tubishu是一名计算机本科生&#xff0c;不定期发送一些在学校的成果供佬们消遣~希望能为佬的编程之路添砖加瓦⭐&#x1f525; 求各位大佬们垂怜&#x1f525;点赞评论一下呗&#x1f525;&#x1f525; 本文专栏 ➡️ 数据结构 …

使用vscode + Roo Code (prev. Roo Cline)+DeepSeek-R1使用一句话需求做了个实验

摘要 使用vscode、Roo Code和deepseek-reasoner进行了一个实验&#xff0c;尝试使用一句话需求来生成小红书封面图片。工具根据需求提供了详细的架构方案&#xff0c;包括技术栈选择、核心模块划分、目录结构建议等。然后&#xff0c;工具自动化地完成了开发和测试&#xff0c;…

vscode环境中用仓颉语言开发时调出覆盖率的方法

在vscode中仓颉语言想得到在idea中利用junit和jacoco的覆盖率&#xff0c;需要如下几个步骤&#xff1a; 1.在vscode中搭建仓颉语言开发环境&#xff1b; 2.在源代码中右键运行[cangjie]coverage. 思路1&#xff1a;编写了测试代码的情况&#xff08;包管理工具&#xff09; …

基于SpringBoot+WebSocket的前后端连接,并接入文心一言大模型API

前言&#xff1a; 本片博客只讲述了操作的大致流程&#xff0c;具体实现步骤并不标准&#xff0c;请以参考为准。 本文前提&#xff1a;熟悉使用webSocket 如果大家还不了解什么是WebSocket&#xff0c;可以参考我的这篇博客&#xff1a; rWebSocket 详解&#xff1a;全双工…

積分方程與簡單的泛函分析8.具連續對稱核的非齊次第II類弗雷德霍姆積分算子方程

1)def求解具連續對稱核的非齊次第II類弗雷德霍姆積分算子方程 设 是定义在上的连续对称核函数&#xff0c; 非齐次第二类弗雷德霍姆积分算子方程的形式为&#xff1a; &#xff0c; 其中是未知函数&#xff0c;是给定的连续函数&#xff0c;是参数。 2)def其特徵值是否一致…

RV1126画面质量四:GOP改善画质

一&#xff0e; 什么是 GOP GOP 实际上就是两个 I 帧的间隔&#xff0c;比方说分辨率是 1920 * 1080 50 帧&#xff0c;假设 GOP 为 5&#xff0c;那就是大概 2s 插入一个 I 帧。我们再 回顾下&#xff0c;H264/H265 的帧结构。H264/H265 分别分为三种帧类型&#xff1a;I 帧、…

一文了解二叉树的基本概念

文章目录 二叉树1二叉树的定义及其主要特征1.1二叉树的定义1.2二叉树的特点1.3二叉树的五种形态1.4二叉树与度为2的有序树的区别1.5几个特殊的二叉树1.6二叉树的性质 2二叉树的存储结构2.1二叉树的顺序存储2.2二叉树的链式存储 二叉树 1二叉树的定义及其主要特征 1.1二叉树的定…

MAX98357A一款数字脉冲编码调制(PCM)输入D类音频功率放大器

MAX98357A是一款数字脉冲编码调制&#xff08;PCM&#xff09;输入D类音频功率放大器&#xff0c;以下是对其的详细介绍&#xff1a; 一、主要特性 音频性能&#xff1a; 提供D类效率与AB类音频性能。支持高达3.2W&#xff08;4Ω负载&#xff0c;5V供电&#xff09;的输出功率…

nacos(基于docker最详细安装)

1、什么是Spring Cloud Spring Cloud是一系列框架的集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发&#xff0c;如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等&#xff0c;都可以用Spring Boot的开发风格做到一键启动和部署。…

78,【2】BUUCTF WEB .[安洵杯 2019]不是文件

进入靶场 解题过程 点击最下面的英文字即可上传图片 新建一个文本文档 里面内容为空 更改名字为 1,2,3,4,0x4f3a363a2268656c706572223a323a7b733a393a22002a00696676696577223b623a313b733a393a22002a00636f6e666967223b733a353a222f666c6167223b7d)#.png 知道id1&#x…

Git 如何将旧仓库迁移新仓库中,但不显示旧的提交记录

一、异常错误 场景&#xff1a;我想把旧仓库迁移新仓库中&#xff0c;放进去之后&#xff0c;新仓库会显示这个项目之前的所有提交&#xff0c;如何不显示这些旧的提交&#xff1f; 二、原因 我们需要将旧仓库迁移新仓库中&#xff0c;但是又不想在新仓库中显示旧的提交记录…

Mysql索引(学习自用)

目录 一、索引概述 优缺点 二、索引结构 1、索引数据结构 2、索引支持结构 3、B树 4、B树 5、hash索引 6、为啥采用B树索引 三、索引分类 四、索引语法 五、索引性能分析 5.1查看执行频率 5.2慢查询日志 5.3profiling 5.4explain 六、索引使用规则 6.1验证索…

PSD是什么图像格式?如何把PSD转为JPG格式?

在图形设计的世界里&#xff0c;Photoshop 文档&#xff08;PSD&#xff09;格式是 Adobe Photoshop 的原生文件格式&#xff0c;它允许设计师保存图像中的图层、蒙版、透明度和不同色彩模式等信息。对于需要进一步编辑的设计作品来说&#xff0c;PSD 文件提供了极大的灵活性。…

基于物联网的风机故障检测装置的设计与实现

1 系统总体设计方案 通过对风机故障检测装置的设计与实现的需求、可行性进行分析&#xff0c;本设计风机故障检测装置的设计与实现的系统总体架构设计如图2-1所示&#xff0c;系统风机故障检测装置采用STM32F103单片机作为控制器&#xff0c;并通过DS18B20温度传感器、ACS712电…

全面评测 DOCA 开发环境下的 DPU:性能表现、机器学习与金融高频交易下的计算能力分析

本文介绍了我在 DOCA 开发环境下对 DPU 进行测评和计算能力测试的一些真实体验和记录。在测评过程中&#xff0c;我主要关注了 DPU 在高并发数据传输和深度学习场景下的表现&#xff0c;以及基本的系统性能指标&#xff0c;包括 CPU 计算、内存带宽、多线程/多进程能力和 I/O 性…

websocket实现

由于安卓资源管理器展示的路径不尽相同,各种软件保存文件的位置也不一定一样.对于普通用户上传文件时,查找文件可能是一个麻烦的事情.后来想到了一个办法,使用pc端进行辅助上传. 文章目录 实现思路1.0 实现定义web与客户端通信数据类型和数据格式web端websocket实现web端对客户…

【科研建模】Pycaret自动机器学习框架使用流程及多分类项目实战案例详解

Pycaret自动机器学习框架使用流程及项目实战案例详解 1 Pycaret介绍2 安装及版本需求3 Pycaret自动机器学习框架使用流程3.1 Setup3.2 Compare Models3.3 Analyze Model3.4 Prediction3.5 Save Model4 多分类项目实战案例详解4.1 ✅ Setup4.2 ✅ Compare Models4.3 ✅ Experime…