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

c++领域展开第十六幕——STL(vector容器的了解以及模拟实现、迭代器失效问题)超详细!!!!

在这里插入图片描述

文章目录

  • 前言
  • 一、vector的介绍和使用
    • 1.1 vector的介绍
    • 1.2 vector的使用
      • 1.2.1 vector的定义
      • 1.2.2 vector iterator 的使用
      • 1.2.3 vector的空间增长问题
      • 1.2.4 vector的增删改查
  • 二、vector在 oj 中的使用
    • 只出现一次的数
    • 删除有序数组中的重复项
    • 杨辉三角
  • 总结

前言

在c++专栏的上一篇博客我们详细讲解了string类的模拟实现
同时在模拟实现过程中也学会了很多
stl的学习就是:能用,明理,能扩展
今天我们来了解 stl 的另外一个容器——vector
fellow me

一、vector的介绍和使用

1.1 vector的介绍

vector
文档链接如上
在这里插入图片描述
文档里面详细介绍了vector
vector有关的 成员函数以及功能都能找到

1.2 vector的使用

学习vector的时候可以多翻翻文档,便于更好的理解

1.2.1 vector的定义

constructor——————构造函数声明接口说明
vector()(重点)————无参构造
vector(size_type n, const value_type& val =value_type())————构造并初始化n个val
vector (const vector& x); (重点) ————————拷贝构造
vector (InputIterator first, InputIterator last);———— 使用迭代器进行初始化构造

代码展示:

 	vector<int> first;                                // 无参构造vector<int> second(4, 100);                       // 构造并初始化 4 个 valvector<int> third(second.begin(), second.end());  // 使用迭代器进行初始化构造vector<int> fourth(third);                       //  拷贝构造

1.2.2 vector iterator 的使用

iterator的使用————接口说明
begin + end(重点)
获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置的iterator/const_iterator
rbegin + rend
获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的reverse_iterator

在这里插入图片描述
在这里插入图片描述
代码展示:

void PrintVector(const vector<int>& v)
{// const对象使用const迭代器进行遍历打印vector<int>::const_iterator it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;
}
	// 使用push_back插入4个数据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;// 使用迭代器进行修改it = v.begin();while (it != v.end()){*it *= 2;++it;}// 使用反向迭代器进行遍历再打印// vector<int>::reverse_iterator rit = v.rbegin();auto rit = v.rbegin();while (rit != v.rend()){cout << *rit << " ";++rit;}cout << endl;

1.2.3 vector的空间增长问题

容量空间————接口说明
size ————————获取数据个数
capacity ——————获取容量大小
empty ———————判断是否为空
resize(重点) ———改变vector的size
reserve (重点) ——改变vector的capacity

  1. capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。
  2. reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
  3. resize在开空间的同时还会进行初始化,影响size。

代码展示:

// 可以试着运行下面代码
// reisze(size_t n, const T& data = T())
// 将有效元素个数设置为n个,如果时增多时,增多的元素使用data进行填充
// 注意:resize在增多元素个数时可能会扩容
void TestVector1()
{vector<int> v;// set some initial content:for (int i = 1; i < 10; i++)v.push_back(i);v.resize(5);v.resize(8, 100);v.resize(12);for (size_t i = 0; i < v.size(); i++)   cout << ' ' << v[i];cout << '\n';
}// 测试vector的默认扩容机制
// vs:按照1.5倍方式扩容
// linux:按照2倍方式扩容
void TestVectorExpand()
{size_t sz;vector<int> v;sz = v.capacity();for (int i = 0; i < 100; ++i) {v.push_back(i);if (sz != v.capacity()) {sz = v.capacity();cout<< sz << '\n';}}
}// 往vecotr中插入元素时,如果大概已经知道要存放多少个元素
// 可以通过reserve方法提前将容量设置好,避免边插入边扩容效率低
void TestVectorExpandOP()
{vector<int> v;size_t sz = v.capacity();v.reserve(100);   // 提前将容量设置好,可以避免一遍插入一遍扩容for (int i = 0; i < 100; ++i) {v.push_back(i);if (sz != v.capacity()){sz = v.capacity();cout << sz << '\n';}}
}

1.2.4 vector的增删改查

vector增删查改—————— 接口说明
push_back(重点) ————尾插
pop_back (重点) ———— 尾删
insert —————————— 在position之前插入val
erase ——————————删除position位置的数据
swap ——————————交换两个vector的数据空间
operator[] (重点) ————像数组一样访问

// 尾插和尾删:push_back/pop_back
void TestVector4()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);auto 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;
}// 任意位置插入:insert和erase,以及查找find
// 注意find不是vector自身提供的方法,是STL提供的算法
void TestVector5()
{// 使用列表方式初始化,C++11新语法vector<int> v{ 1, 2, 3, 4 };// 在指定位置前插入值为val的元素,比如:3之前插入30,如果没有则不插入// 1. 先使用find查找3所在位置// 注意:vector没有提供find方法,如果要查找只能使用STL提供的全局findauto pos = find(v.begin(), v.end(), 3);if (pos != v.end()){// 2. 在pos位置之前插入30v.insert(pos, 30);}vector<int>::iterator it = v.begin();while (it != v.end()) {cout << *it << " ";++it;}cout << endl;pos = find(v.begin(), v.end(), 3);// 删除pos位置的数据v.erase(pos);it = v.begin();while (it != v.end()) {cout << *it << " ";++it;}cout << endl;
}// operator[]+index 和 C++11中vector的新式for+auto的遍历
// vector使用这两种遍历方式是比较便捷的。
void TestVector6()
{vector<int> v{ 1, 2, 3, 4 };// 通过[]读写第0个位置。v[0] = 10;cout << v[0] << endl;// 1. 使用for+[]小标方式遍历for (size_t i = 0; i < v.size(); ++i)cout << v[i] << " ";cout << endl;vector<int> swapv;swapv.swap(v);  //  vector 的 swap使用cout << "v data:";for (size_t i = 0; i < v.size(); ++i)cout << v[i] << " ";cout << endl;// 2. 使用迭代器遍历cout << "swapv data:";auto it = swapv.begin();while (it != swapv.end()){cout << *it << " ";++it;}// 3. 使用范围for遍历for (auto x : v)cout << x << " ";cout << endl;
}

二、vector在 oj 中的使用

只出现一次的数

只出现一次的数 I
在这里插入图片描述
还是比较简单的,就是按位异或就行,重复的元素按位异或之后就变成 0 了,只剩下出现一次的元素

class Solution 
{
public:int singleNumber(vector<int>& nums) {int value = 0;for(auto e : nums){value ^= e;}return value;}
};

删除有序数组中的重复项

删除有序数组中的重复项
在这里插入图片描述
还是比较简单的,双指针完美解决,不知道的可以去我的——code ability 专栏看看

class Solution 
{
public:int removeDuplicates(vector<int>& nums) //前后指针{int n = nums.size();int left = 0;for(int right = 1; right < n; right++){if(nums[right] != nums[left]){if(right == ++left)continue;else{nums[left] = nums[right];}}}return left+1;}
};

杨辉三角

杨辉三角
在这里插入图片描述
这里有个实时扩容的问题, 因为杨辉三角每一行的个数都不一样
其他的处理就比较简单了,话不多说,看代码

class Solution {
public:vector<vector<int>> generate(int numRows) {vector<vector<int>>  vv(numRows);for(int i = 0; i < numRows; i++){vv[i].resize(i + 1, 1);}for(int i = 2; i < vv.size(); i++){for(int j = 1; j < vv[i].size() - 1; j++){vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];}}return  vv; }
};

其实写了几道题目下来,vector和数组的用法其实差不多,但是vector还是会好一些
毕竟有了封装,使得很多东西都标准化,同时作为容器,在后面学习配接器的时候还是很爽的

总结

今天认识了vector以及vector的使用,学习vector的第一步算是到这里啦
下一篇博客就是来深究探讨vector,自己模拟实现一遍
不要走开,小编持续更新中~~~~

在这里插入图片描述

相关文章:

c++领域展开第十六幕——STL(vector容器的了解以及模拟实现、迭代器失效问题)超详细!!!!

文章目录 前言一、vector的介绍和使用1.1 vector的介绍1.2 vector的使用1.2.1 vector的定义1.2.2 vector iterator 的使用1.2.3 vector的空间增长问题1.2.4 vector的增删改查 二、vector在 oj 中的使用只出现一次的数删除有序数组中的重复项杨辉三角 总结 前言 在c专栏的上一篇…...

ubuntu2404 安装 过程中 手动设置网络

ubuntu2404 安装 过程中 手动设置网络 https://blog.csdn.net/2401_83947353/article/details/138454379 6.1 可以直接Done&#xff08;不配置P&#xff09; 6.2 可以配置ip地址&#xff0c;选择manual 6.2.1 search domains填 6.2.2 search domains不填 6.3 更深层次的…...

去北京的前端实习经历

趁现在对这部分还有深刻的感受记忆&#xff0c;赶紧记录下来。因为工作久了会发现真的对以前的事记不起来了。 公司&#xff1a; 北京的实习公司首先有学长学姐在&#xff0c;而且这个公司知名度还挺高的&#xff0c;但是工资比较低&#xff0c;3k左右吧&#xff0c;但是管2顿…...

QT创建项目(项目模板、构建系统、选择类、构建套件)

1. 项目模版 项目类型界面技术适用场景核心依赖模块开发语言Qt Widget ApplicationC Widgets传统桌面应用&#xff08;复杂控件&#xff09;Qt WidgetsCQt Console Application无 GUI命令行工具、服务Qt CoreCQt Quick ApplicationQML/Quick现代跨平台应用&#xff08;动画/触…...

力扣热题 100:动态规划专题经典题解析

系列文章目录 力扣热题 100&#xff1a;哈希专题三道题详细解析(JAVA) 力扣热题 100&#xff1a;双指针专题四道题详细解析(JAVA) 力扣热题 100&#xff1a;滑动窗口专题两道题详细解析&#xff08;JAVA&#xff09; 力扣热题 100&#xff1a;子串专题三道题详细解析(JAVA) 力…...

变量赋值汇编

一、核心概念 寄存器&#xff1a;CPU内部的高速存储单元&#xff08;如EAX、EBX、x86中的RAX、ARM中的R0等&#xff09; 内存地址&#xff1a;变量存储在内存中的位置&#xff08;如 0x1000&#xff09; 指令&#xff1a;操作寄存器和内存的命令&#xff08;如 MOV, STR, LDR…...

页面白屏出现的原因

&#x1f916; 作者简介&#xff1a;水煮白菜王&#xff0c;一位前端劝退师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 前端专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧和知识归纳总结✍。 感谢支持&#x1f495;&#x1f495;&#…...

【大模型统一集成项目】让 AI 聊天更丝滑:WebSocket 实现流式对话!

&#x1f31f; 在这系列文章中&#xff0c;我们将一起探索如何搭建一个支持大模型集成项目 NexLM 的开发过程&#xff0c;从 架构设计 到 代码实战&#xff0c;逐步搭建一个支持 多种大模型&#xff08;GPT-4、DeepSeek 等&#xff09; 的 一站式大模型集成与管理平台&#xff…...

boarding_passes(登机牌)表的作用

boarding_passes&#xff08;登机牌&#xff09;表的作用 boarding_passes 这张表的主要作用是记录旅客的登机信息&#xff0c;包括&#xff1a; 票号 (ticket_no) - 关联到 tickets 表&#xff0c;表示这张票属于哪个旅客。航班 ID (flight_id) - 关联到 flights 表&#xf…...

【2025】Electron Git Desktop 实战一(上)(架构及首页设计开发)

源代码仓库&#xff1a; Github仓库【electron_git】 Commit &#xff1a; bb40040 Github Desktop 页面分析 本节目标&#xff1a; 1、实现类似Github Desktop的「空仓库」提示页 2、添加本地仓库逻辑编写从 Github Desktop 我们看到 他的 主要页面分为三个区域 Head头部区域…...

14 | fastgo 三层架构设计

提示&#xff1a; 所有体系课见专栏&#xff1a;Go 项目开发极速入门实战课&#xff1b; 在实现业务代码之前&#xff0c;还需要先设计一个合理的软件架构。一个好的软件架构不仅可以大大提高项目的迭代速度&#xff0c;还可以降低项目的阅读和维护难度。目前&#xff0c;行业中…...

【机器学习-基础知识】统计和贝叶斯推断

1. 概率论基本概念回顾 1. 概率分布 定义: 概率分布(Probability Distribution)指的是随机变量所有可能取值及其对应概率的集合。它描述了一个随机变量可能取的所有值以及每个值被取到的概率。 对于离散型随机变量,使用概率质量函数来描述。对于连续型随机变量,使用概率…...

面向对象Demo01

面向对象 什么是面向对象 回顾方法的定义 package oop; ​ import java.io.IOException; ​ public class Demo01 {public static void main(String[] args) {}//public String sayHello() {return "hello, world!";}public void sayHi() {return;}public int max(i…...

C++设计模式-抽象工厂模式:从原理、适用场景、使用方法,常见问题和解决方案深度解析

一、模式基本概念 1.1 定义与核心思想 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是创建型设计模式的集大成者&#xff0c;它通过提供统一的接口来创建多个相互关联或依赖的对象族&#xff0c;而无需指定具体类。其核心思想体现在两个维度&#xff1a; …...

solana区块链地址生成

solana官网地址&#xff1a;https://solana.com 先引入相关依赖solana/web3.js;bip39;ethereumjs/wallet 生成助记词 const mnemonic bip39.generateMnemonic(); 生成种子 const seed bip39.mnemonicToSeedSync(mnemonic); 生成密钥对 const root hdkey.EthereumHDKey.from…...

基于python的升级队列加速决策

a-f大等级是3级 a-c建筑每升1级分别需要8天 d-f建筑每升1级分别需要10天 目前以下建筑队列正在从0级升至1级 建筑A升级需要7天05&#xff1a;16&#xff1a;20 建筑b升级需要06&#xff1a;06&#xff1a;54 建筑c升级需要00&#xff1a;37&#xff1a;00 建筑d升级需要…...

Ragflow技术栈分析及二次开发指南

Ragflow是目前团队化部署大模型+RAG的优质方案,不过其仍不适合直接部署使用,本文将从实际使用的角度,对其进行二次开发。 1. Ragflow 存在问题 Ragflow 开源仓库地址:https://github.com/infiniflow/ragflow Ragflow 当前版本: v0.17.0 Ragflow 目前主要存在以下问题: …...

vue上传文件的请求头携带token校验、和携带另外的参数请求

拿element plus UI库举例&#xff0c;&#xff08;不使用element plus的话js方法通用&#xff09;&#xff1a; <template><el-upload class"upload-demo":http-request"myUploadHttp" action"https://run.mocky.io/v3/9d059bf9-4660-45f2-…...

MySQL的 where 1=1会不会影响性能?

在MySQL中&#xff0c;WHERE 11 是一种常见的SQL编写技巧&#xff0c;通常用于动态生成SQL语句时简化条件拼接。虽然它看起来多余&#xff0c;但在实际使用中&#xff0c;WHERE 11 对性能的影响可以忽略不计。以下是详细分析&#xff1a; 1. WHERE 11 的作用 WHERE 11 是一个恒…...

MyBatis 中SQL 映射文件是如何与 Mapper 接口关联起来的? MyBatis 如何知道应该调用哪个 SQL 语句?

1. 命名空间 (Namespace): SQL 映射文件 (XML): 在 SQL 映射文件的 <mapper> 根元素中&#xff0c;有一个 namespace 属性。这个 namespace 属性的值必须是 Mapper 接口的全限定名&#xff08;包名 接口名&#xff09;。 <mapper namespace"com.example.mapper.…...

SICK Ranger3源码分析——断线重连

前言 本文可在https://paw5zx.github.io/SICK-Ranger3-source-code-analysis-01/中阅读&#xff0c;体验更佳 简单分析一下SICK Ranger3源码中断线重连的实现&#xff0c;这一块算是比较容易的&#xff0c;先择出来分析一下。 代码示例仅贴出关键部分以便分析 使用SDK版本为…...

1.7 双指针专题:三数之和(medium)

1.题目链接 15. 三数之和 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/3sum/submissions/609626561/ 2.题目描述 给你⼀个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满⾜ i ! j、i ! k 且 j ! k &#xff0c;同时…...

【JavaEE】Spring Boot配置文件

目录 一、Spring Boot配置文件简介二、properties 配置⽂件说明2.1 properties 基本语法2.2 value("${}")读取配置⽂件 三、yml 配置文件说明3.1 yml 基本格式3.2 yml 配置数据类型 及 读取3.3 yml配置对象及读取ConfigurationProperties(prefix "")3.4 配…...

行为模式---策略模式

概念 策略模式是一种行为设计摸是&#xff0c;它的核心思想是将一些列的算法封装成独立的对象&#xff0c;并使它们可以相互替换&#xff0c;通过上下文进行调用。 策略模式通过算法抽象为独立的策略类&#xff0c;客户端可以根据自身需求选择不同的策略类来完成任务、这种方…...

Word 小黑第15套

对应大猫16 修改样式集 导航 -查找 第一章标题不显示 再选中文字 点击标题一 修改标题格式 格式 -段落 -换行和分页 勾选与下段同页 添加脚注 &#xff08;脚注默认位于底部 &#xff09;在脚注插入文档属性&#xff1a; -插入 -文档部件 -域 类别选择文档信息&#xff0c;域…...

OSPF:虚链路

一、虚链路概念 在OSPF中&#xff0c;虚链路&#xff08;Virtual Link&#xff09; 是一种逻辑连接&#xff0c;用于解决因网络设计或扩展导致的区域无法直接连接到骨干区域&#xff08;Area 0&#xff09;的问题。它是通过中间区域&#xff08;Transit Area&#xff09;在两个…...

Ubuntu 22.04 安装配置 FTP服务器 教程

今天搞定在 Ubuntu 22.04 系统上安装和配置 VSFTPD &#xff0c;还会涉及防火墙设置、SSL/TLS 设置&#xff0c;以及创建专门登录 FTP 服务器的账户。开始&#xff01; 一、安装 VSFTPD 首先&#xff0c;咱得让系统知道有啥新软件包可以安装。打开终端&#xff0c;输入下面这…...

基于 Selenium 的软件测试方法研究

一、引言 在软件开发的漫长征程中&#xff0c;软件测试宛如一座坚实的堡垒&#xff0c;守护着软件质量的大门。随着互联网技术的飞速发展&#xff0c;Web 应用程序如雨后春笋般涌现&#xff0c;其功能的复杂性和用户交互的多样性不断增加。在这样的背景下&#xff0c;传统的手动…...

网络安全事件响应--应急响应(windows)

应用系统日志 Windows主要有以下三类日志记录系统事件&#xff1a;应用程序日志、系统日志和安全日志。 系统和应用程序日志存储着故障排除信息&#xff0c;对于系统管理员更为有用。安全日志记录着事件审计信息&#xff0c;包括用户验证&#xff08;登录、远程访问等&#x…...

DataEase:一款国产开源数据可视化分析工具

DataEase 是由飞致云开发的一款基于 Web 的数据可视化 BI 工具&#xff0c;支持丰富的数据源连接&#xff0c;能够通过拖拉拽方式快速制作图表&#xff0c;帮助用户快速分析业务数据并洞察其趋势&#xff0c;为企业的业务改进与优化提供支持。 DataEase 的优势在于&#xff1a;…...