【C++】详解vector二维数组的全部操作(超细图例解析!!!)

目录

一、前言

二、 深度理解vector 的二维数组(重点!)

 三、vector 二维数组的空间理解(重点!)

✨问题分析

✨如何合理定制vector的内存空间

 四、vector 二维数组的初始化

五、vector 二维数组的 添加与删除

✨添加一行

✨添加一列

✨删除一行

✨删除一列

六、常考面试题

 七、共勉


一、前言

    最近在刷 Leetcode 的时候,发现 vector 的二维数组操作 都还没弄明白吗,但是STL的强大是众所周知滴,早晚都是要解决滴,因此专门写下这篇文章,以供自己复习和各位老铁使用,快速的回忆vector的用法,让你找回自信,不用再竞赛的时候颜面尽失。
    vector 的一维操作可以看看之前这篇文章哦:vector 详解

二、 深度理解vector 的二维数组(重点!)

     在解决大部分算法问题的时候,通常都会遇到二维数组 vector<vector<int>> table, 但是不知道怎么对其进行初始化(初始化时指定二维容器的大小),于是通过查阅了很多资料,将其总结如下:

vector<vector<int>> table(size1, vector<int>(size2, 0));

 代码说明:声明一个名为 table 的容器,其元素为 vector的容器。简单来说类似一个int型的二维数组。

这样,就得到了一个如下图所示的二维容器。 

 具体代码的内容,可以这样理解:

 图中,我将外围容器table的初始化参数分成了两部分 A、B 

  • A: table外围容器的大小
  • B: table外围容器的内容,即 size1个vector型的元素。
  • B1:内部容器的大小
  • B2:内部容器的内容

观察规律,可以得出如下的初始化格式:容器(大小,内容)

 三、vector 二维数组的空间理解(重点!)

      我们都知道,在 C语言 中,创建一维数组或者更高维度的数组时,都是需要提前给他分配大小的。
      而在 C++的 vector 容器 中我们并不需要那么做,我们可以直接push进去后,根据下标访问它,如:

 ✨问题分析

	vector<int> a;a.push_back(1);cout << a[0];

 由此处诞生出了两个问题

  1.  在处理小数据是没问题的,但处理大数据时,vector 会重新分配内存,一般会把容量(所分配好的内存空间)翻倍,这将导致出现大量的冗余空间。
  2. 在对二维的数组创建时,会出现创造失败的情况,如下面的情况就会报错:
vector<vector<int>> a;  // 创建一个空的二维向量a
a[0].push_back(1);       // 尝试访问a的第一个元素(即空向量),然后在其上调用push_back()方法,但是a目前为空,没有索引为0的元素,因此这将导致访问越界错误。
cout << a[0][0];         // 试图输出a的第一个元素的第一个元素,但是由于a为空,这也会导致访问越界错误。

错误原因: 

  1. 尝试访问 a 的第一个元素(即空向量),然后在其上调用push_back()方法,但是a目前为空,没有索引为 0 的元素,因此这将导致访问越界错误。
  2.  试图输出 a 的第一个元素的第一个元素,但是由于a为空,这也会导致访问越界错误。

✨如何合理定制vector的内存空间

首先要明白,我们第二个问题的出现,其实就是因为第一个问题,那么我们逐个分析一下:

  • 对于 vector 的 .size() 代表查询它的 动态数组vector中有多少个有效数。
  • 对于 vector 的.capacity()代表查询它的容量(最多放多少个数)。

 如何理解这两个函数接口呢?

  • resize(Container::size_type n)强制把容器改为容纳n个元素。调用resize之后,size将会返回n。如果n小于当前大小,容器尾部的元素会被销毁。如果n大于当前大小,新默认构造的元素会添加到容器尾部。如果n大于当前容量,在元素加入之前会发生重新分配。
  • reserve(Container::size_type n)强制容器把它的容量改为至少n,提供的n不小于当前大小。这一般强迫进行一次重新分配,因为容量需要增加。(如果n小于当前容量,vector忽略它,这个调用什么都不做,string可能把它的容量减少为size()和n中大的数,但string的大小没有改变。

 【总结】上述两方法的区别

  1. reserve表示容器预留空间,但并不是真正的创建对象,需要通过insert()或push_back()等创建对象resizee既分配了空间,也创建了对象
  2. reserve只修改capacity大小,不修改size大小,resize既修改capacity大小,也修改size大小。
  3. resize带两个参数,一个表示容器大小,一个表示初始值(默认为0)。reserve只带一个参数,表示容器预留的大小。
  4. 因此,我们在对一维数组push前,可以来一个reverse,这样在不断push的过程中就不会发生重新分配了。如:vector<int> a; a.reserve(1000);

所以针对问题二出现的原因:vector 直接根据下标访问必须要先push,存在数才行。而上面的代码想直接对第一行里面的各个元素进行访问或者修改时绝对不行的。但是相反,如果我们先对第一行进行赋值,然后再访问,这样又是可以的,如:

vector<vector<int>> a;
a.push_back(vector<int>()); // 添加一个空的一维向量
a[0].push_back(1);          // 现在可以向a的第一个元素(现在是一个向量)添加元素了
cout << a[0][0];            // 输出1

 因此,想要直接对第一行第一列的进行调整,就需要我们预先给他点空间了!!

 四、vector 二维数组的初始化

首先,要先知道:二维 vector 如何获得行数和列数。

vector<vector<int>> a(r, vector<int>(c));
int row = a.size();          //获取行数
int column = a[0].size();    //获取列数

 方法一:定义时,直接初始化
(1)下面定义的是行为r,列为c的二维数组

vector<vector<int>> ans(r, vector<int>(c));

(2)下面定义的是行为r,列为c的二维数组,初始值为0

vector< vector<int> > a(r, vector<int>(c, 0)); 

方法二:用resize来提前构建

(下面定义的是行为r,列为c的二维数组,初始值为0–因为resize默认为0)

vector<vector<int>> new_mat(r);//注意这个r是不可缺少的,规定其有多少行
for(int i=0 ;i<r; i++) //二维vector的初始化时有要求的
{new_mat[i].resize(c);
}

方法三:每行不一定几个数,就是想对每行的列进行操作

vector<vector<int>>mat(r);//每行的定义
mat[i].push_back(1);//这就是该第i-1行的插入一个元素,值为1

 

五、vector 二维数组的 添加与删除

✨添加一行

//插入一行数组:将in_row数组插入到第2行! 
vector<int> in_row(5,6);//初始化一个数组,包含5个元素并且全为6
a.insert(a.begin()+2,in_row);

✨添加一列

for(int i=0;i<a.size();i++)
{a[i].insert(a[i].begin()+2,9);
}

✨删除一行

a.erase(a.begin() + 2, a.begin() + 3);

✨删除一列

//删除a的第二列for (int i = 0; i < a.size(); i++){a[i].erase(a[i].begin() + 2, a[i].begin() + 3);}

六、常考面试题

题目:杨辉三角形
链接:118. 杨辉三角

class Solution {
public:vector<vector<int>> generate(int numRows) {// 生成一个二维数组vector<vector<int>> vv;// 给二维数组开辟有效空间---开辟numRows行vv.resize(numRows);for(int i = 0;i<numRows;i++){//每一行开辟i+1个 空间,并且进行初始化为 0 vv[i].resize(i+1,0);//每一行的第一个和最后一个为 1vv[i].front() = vv[i].back() = 1;}// 每一次都从第3行开始,第二个开始遍历for(int i = 2;i<numRows;i++){for(int j = 1;j<i;j++){vv[i][j] = vv[i-1][j-1] + vv[i-1][j];}}return vv;}
};

 七、共勉

 以下就是我对【C++ STL】vector 二维数组 的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对C++STL库的理解,请持续关注我哦!!!

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

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

相关文章

性能优化 - 你能说一说,为什么做了骨架屏,FCP的指标还是没有提升吗

难度级别:中高级及以上 提问概率:80% FCP的全程是First Contentful Paint,是衡量网页性能的一个重要指标,很多人把FCP理解为元素内容首次渲染到浏览器上的时间。但由于现在比较流行的Vue或是React项目中,HTML文档最初只有一个id为app的DIV…

【Labview】虚拟仪器技术

一、背景知识 1.1 虚拟仪器的定义、组成和应用 虚拟仪器的特点 虚拟仪器的突出特征为“硬件功能软件化”&#xff0c;虚拟仪器是在计算机上显示仪器面板&#xff0c;将硬件电路完成信号调理和处理功能由计算机程序完成。 虚拟仪器的组成 硬件软件 硬件是基础&#xff0c;负责将…

YOLOv5改进--轻量化YOLOv5s模型

文章目录 1、前言2、轻量化模型结构&#xff1a;3、模型对比4、训练结果图5、目标检测文章 1、前言 在边缘设备的场景下&#xff0c;目前的YOLOv5s&#xff0c;虽然能够快速实现目标检测&#xff0c;但是运行速度依旧稍慢点&#xff0c;本文在牺牲一点精度前提下&#xff0c;提…

Web漏洞-文件上传常见验证

后缀名&#xff1a;类型&#xff0c;文件头等 后缀名&#xff1a;黑白名单 文件类型&#xff1a;MIME信息 文件头&#xff1a;内容头信息 常见黑名单&#xff08;明确不允许上传的格式后缀&#xff09;&#xff1a;asp、php、jsp、aspx、cgi、war &#xff08;如果没有完整…

nacos derby.log无法的读取+derby数据库启动失败分析解决

排查思路分析 日志报错&#xff1a; derby.log文件权限不够&#xff08;root权限&#xff09;&#xff0c;无法读取&#xff0c;我用普通用户启动。 使用命令chown xx:xx derby.log修改属主和属组为普通用户后&#xff0c;又报出其他错误。 数据库启动不了&#xff0c;无…

Composer Windows 安装

Composer 的下载地址为&#xff1a;Composer 1 运行安装程序 当启动安装程序后单击下一步继续。 选择 PHP 路径 如果你的计算机上没有安装 PHP 的话&#xff0c;Composer 的安装无法继续。 你需要选择你本地安装的 PHP 路径。 配置代理地址 默认的情况下&#xff0c;可以不…

基于starganvc2的变声器论文原理解读

数据与代码见文末 论文地址&#xff1a;https://arxiv.org/pdf/1907.12279.pdf 1.概述 什么是变声器&#xff0c;变声器就是将语音特征进行转换&#xff0c;而语音内容不改变 那么我们如何构建一个变声器呢&#xff1f; 首先&#xff0c;我们肯定不能为转换的每一种风格的声…

JavaEE初阶——多线程(一)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享多线程的第一部分:引入线程以及创建多线程的几种方式 此文章是建立在前一篇文章进程的基础上的 如果有不足的或者错误的请您指出! 1.认识线程 我们知道现代的cpu大多都是多核心…

【Figma】安装指南及基础操作

先前做UI设计一直都是用PS等绘图软件设计&#xff0c;但发现在纠结像素和排版问题上会花很多时间&#xff0c;再加上AI没来得及上手&#xff0c;就需要迅速出成图&#xff0c;此时通过论坛发现了figma&#xff0c;基本上可以满足足够的需求&#xff0c;并且可以在windows系统上…

SVG图标显示

SVG图标显示 1.安装SharpVectors.Wpf包 2.添加引用 xmlns:svgc"http://sharpvectors.codeplex.com/svgc/"3.加载svg文件&#xff0c;生成操作选择资源(Resource) 4.UI界面显示SVG图像 <Button Click"OnSaveFileClick" ToolTip"Save Svg File…

武汉星起航:跨境电商领域崭露头角,以实战经验引领行业新潮流

随着全球经济的演进&#xff0c;跨境电商正成为国际贸易的引擎&#xff0c;而武汉星起航电子商务有限公司凭借其丰富实战经验和专业团队&#xff0c;在这一领域取得了引人瞩目的成绩。公司成立于2020年&#xff0c;自2017年起紧紧围绕亚马逊自营店铺&#xff0c;致力于为合作伙…

基于Spring Boot+Vue的在线拍卖系统

随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单管理、…

初学python记录:力扣1600. 王位继承顺序

题目&#xff1a; 一个王国里住着国王、他的孩子们、他的孙子们等等。每一个时间点&#xff0c;这个家庭里有人出生也有人死亡。 这个王国有一个明确规定的王位继承顺序&#xff0c;第一继承人总是国王自己。我们定义递归函数 Successor(x, curOrder) &#xff0c;给定一个人…

通用接口开放平台设计与实现——(30)消息服务端之消息重发优化

背景 消息服务通信机制为异步&#xff0c;且网络连接不是100%可靠&#xff0c;会因为网络闪断问题丢失消息&#xff0c;作为企业应用&#xff0c;需要保证业务消息传输的可靠性&#xff0c;需实现以下机制&#xff1a; a)发送方重发机制&#xff1a;消息发送方对未收到响应的消…

酱油行业市场需求及广阔前景分析

随着居民消费升级&#xff0c;对高品质生活的向往使得酱油市场需求持续增长。消费者对酱油的功能性需求日益细分&#xff0c;追求健康、天然与个性化的产品特性&#xff0c;从而推动了市场的多元化进步。 同时&#xff0c;餐饮业的蓬勃发展以及外卖市场的扩大&#xff0c;均为酱…

【Django开发】前后端分离美多商城项目第6篇:用户部分,1. 业务说明【附代码文档】

美多商城项目4.0文档完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;美多商城&#xff0c;项目准备1.B2B--企业对企业,2.C2C--个人对个人,3.B2C--企业对个人,4.C2B--个人对企业,5.O2O--线上到线下,6.F2C--工厂到个人。项目准备&#xff0c;配置1. 修改set…

通用分布式锁组件

通用分布式锁组件 1 Redisson1.1介绍1.2 为什么要使用Redisson实现分布式锁1.2.1 锁续期的问题1.2.2 获取锁尝试的问题1.2.3 可重入问题 1.3 Wath Dog的自动延期机制1.4 快速了解1.5 项目集成 2 定义通用分布式锁组件2.1 实现思路分析2.2 定义注解2.3 定义切面2.4 使用锁2.5.工…

STL之string模拟实现

面试题&#xff1a;简易版string(深拷贝与浅拷贝的问题) 如果要实现简易版的string 无需涉及增容问题&#xff0c;成员变量可以不用存储容量和元素个数 构造函数 错误示范 class string {string(): _str(nullptr){}string(const char* str): _str(str){}char& operator[](s…

Redis数据库:高可用(主从复制、哨兵模式、cluster集群)

目录 前言 一、Redis数据库高可用 二、Redis 主从复制 1、Redis主从复制概述 1.1 Redis主从复制概念 1.2 Redis主从复制的作用 1.3 Redis主从复制的流程 2、搭建Redis主从复制 2.1 环境部署 2.2 主服务器修改配置文件 2.3 从服务器修改配置文件 2.4 测试主从复制效…

负氧离子监测站解析

TH-FZ4防腐木负氧离子监测站&#xff0c;作为一种独特的空气质量监测设备&#xff0c;以其独特的优势在生态环保领域发挥着日益重要的作用。这种监测站不仅具备防腐木材质带来的天然美感与耐久性&#xff0c;更结合了先进的负氧离子监测技术&#xff0c;为环境保护和生态旅游等…