【C++初阶】一篇手撕vector类

news2024/11/28 20:59:45

vector类

    • 一,vector的介绍
    • 二,vector的使用
      • 2.1 vector的定义
      • 2.2 vector iterator
      • 2.3 vector空间增长问题
      • 2.4 vector增删查改
      • 2.5 vector<char> 可以替代 string 嘛?

一,vector的介绍

  • vector 是表示可变大小数组序列容器。
  • 就像数组一样,vector 也采用连续的存储空间来存储元素。也就意味着可以采用小标对 vector 的元素进行访问,和数组处理一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
  • 本质讲,vector 使用动态分配数组来存储它的元素。当新元素插入时,为了增加存储空间,这个数组需要被重新分配大小。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价较高的任务,因为每当一个新的元素加入到容器的时候,vector 并不会每次都重新分配大小。
  • vector 分配空间策略:vector 会分配一些额外的空间以适应可能的增长,因此存储空间(容量)比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候实在常数时间复杂度完成的。
  • 因此,vector 占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长
  • 与其它的动态序列容器相比(如:deque、list、forward_list),vector 在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率会比较低。

二,vector的使用

vector 学习时一定要学会查看文档:vector的文档介绍,vector 在实际中非常重要,在实际中我们熟悉常用的接口就可以,下面列出了需要我们重点掌握的接口。

2.1 vector的定义

在这里插入图片描述
小Tips:size_type 表示一个无符号整数类型,value_type 是第一个模板参数,也就是要存储的数据类型。使用迭代器区间的构造函数是函数模板,只要是满足 Input 类型的迭代器都可以使用该构造函数。

int TestVector1()
{
    vector<int> first;                                
    vector<int> second(4, 100);                       
    vector<int> third(second.begin(), second.end());  
    vector<int> fourth(third);                       

    int myints[] = { 16,2,77,29 };
    vector<int> fifth(myints, myints + sizeof(myints) / sizeof(int));

    cout << "The contents of fifth are:";
    for (vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
        cout << ' ' << *it;
    cout << '\n';

    return 0;
}

2.2 vector iterator

在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述

void PrintVector(const vector<int>& v)
{
	// const对象使用const迭代器进行遍历打印
	vector<int>::const_iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

2.3 vector空间增长问题

在这里插入图片描述

  • vs 和 g++ 的扩容机制有所不同,vs 下 capacity 是按照 1.5 倍增长的,g++ 是按照 2 倍增长的。vs 是 PJ 版本 STL,g++ 是 SGI 版本 STL。
  • reserve 只负责开辟空间,如果确定知道需要多少空间,reserve 可以缓解 vector 增容的代价缺陷问题。
  • resize 在开空间的同时还会进行初始化,影响 成员变量 _size。
void TestVectorExpand()
{
    size_t sz;
    vector<int> v;
    sz = v.capacity();
    cout << "making v grow:\n";
    for (int i = 0; i < 100; ++i)
    {
        v.push_back(i);
        if (sz != v.capacity())
        {
            sz = v.capacity();
            cout << "capacity changed: " << sz << '\n';
        }
    }
}

vs下的结果:
在这里插入图片描述

Linux下的结果:
在这里插入图片描述
小Tips:如果已经确定 vector 中要存储元素的大概个数,可以提前将空间设置足够,就可以避免边插入边扩容导致效率低下的问题。

void TestVectorExpandOP()
{
    vector<int> v;
    size_t sz = v.capacity();
    v.reserve(100); // 提前将容量设置好,可以避免一遍插入一遍扩容
    cout << "making bar grow:\n";
    for (int i = 0; i < 100; ++i)
    {
        v.push_back(i);
        if (sz != v.capacity())
        {
            sz = v.capacity();
            cout << "capacity changed: " << sz << '\n';
        }
    }
}

2.4 vector增删查改

在这里插入图片描述

//经典的错误
void Testerro()
{
    vector<int> v1;
    v1.reserve(10);
    for (size_t i = 0; i < 10; i++)
    {
        v1[i] = i;
    }
}

注意:上面的代码虽然给 v1 提前开了 10 个空间,但是 v1 中的有效元素个数还是 0,即 v1.size() 的返回值是0,这样一来我们就不能直接通过下标去访问 vector 对象中的每一个元素,因为 operator[ ] 实现中的第一步就是检查下标的合理性,防止越界访问,执行 assert(pos < _size),而此时 _size 是 0,就会出错。上面的代码只需要把 reserve 改成 resize 就可以正常运行,因为 resize 会改变 _size 的大小。如果硬要使用 reserve 提前开空间,那么接下来要使用 push_back 来插入数据。

2.5 vector 可以替代 string 嘛?

答案是不可以,虽然他们俩的底层本质上都是动态增长的数组,但是 string 字符串的结尾默认有 \0,可以更好的兼容 C 接口,而 vector 的结尾默认是没有 \0 的,需要我们自己插入。

💘不知不觉,【C++初阶】一篇手撕vector类 学习告一段落。通读全文的你肯定收获满满,让我们继续为C++学习共同奋进!!!

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

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

相关文章

[数据集][目标检测]手钳检测数据集VOC+YOLO格式141张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;141 标注数量(xml文件个数)&#xff1a;141 标注数量(txt文件个数)&#xff1a;141 标注类别…

加载dvb文件出错解决方案

1、在c: \Windows\System32文件夹下&#xff0c;放入fm2.0.dll&#xff08;此文件已资源绑定在本文章&#xff09;文件 2、若还是不行&#xff0c;可尝试&#xff1a; 3、或重装CAD vba vba下载官网地址&#xff1a;下载适用于 Inventor 的 Microsoft VBA 模块 https://www…

Spring AI集成Ollama+llava:7b:实战探索大模型的多模态应用

前面的文章介绍的基本上都是单一数据格式的输入处理&#xff0c;比如输入文本输出文本的Chat模型、输入文本输出图片的图片模型、输入文本输出音频的模型等。本篇文章将介绍如何实现同时处理多种类型的数据格式&#xff1f; 什么是多模态 多模态是指模型同时理解和处理来自各种…

初识指针の学习笔记

目录 1>>前言 2>>内存和地址 3>>指针变量和地址 3.1取地址和解引用 3.2>>指针类型是什么&#xff1f; 3.3>>指针变量占用空间 4>>指针变量类型的意义 4.1>>指针的解引用 4.2>>指针-整数 5>>关于指针的运算 5…

「OC」暑假第三周——天气预报的仿写

「OC」暑假第三周——天气预报的仿写 文章目录 「OC」暑假第三周——天气预报的仿写写在前面预览UItableView嵌套UICollectionView毛玻璃效果SVGKit库的使用简单的动画实现主页之中详情页的编写总结 写在前面 天气预报作为暑假最后的一个项目&#xff0c;算得上我觉得有点用的…

西门子PLC跟汇川H5U系列PLC标签方式以太网通讯的快速实现方案

PLC通讯智能网关IGT-DSER模块支持汇川、西门子、三菱、欧姆龙、罗克韦尔AB、GE等各种品牌的PLC之间通讯&#xff0c;同时也支持PLC与Modbus协议的变频器、智能仪表等设备通讯。网关有多个网口、串口&#xff0c;也可选择WIFI无线通讯。PLC内无需编程开发&#xff0c;在智能网关…

金九银十秋招大模型岗位攻略来了,已收offer,非常详细收藏我这一篇就够了

秋季招聘季节是求职者寻找新机会的重要时期&#xff0c;特别是对于想要进入大模型领域的专业人士来说。以下是一份大模型学习攻略和应聘攻略&#xff0c;帮助你为秋季招聘做好准备&#xff1a; 大模型学习攻略 理解大模型基础 学习AI基础&#xff1a;了解机器学习、深度学习的…

[数据集][目标检测]扳手检测数据集VOC+YOLO格式1042张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1042 标注数量(xml文件个数)&#xff1a;1042 标注数量(txt文件个数)&#xff1a;1042 标注…

论文阅读1 Scaling Synthetic Data Creation with 1,000,000,000 Personas

Scaling Synthetic Data Creation with 1,000,000,000 Personas 链接&#xff1a;https://github.com/tencent-ailab/persona-hub/ 文章目录 Scaling Synthetic Data Creation with 1,000,000,000 Personas1. 摘要2. 背景2.1 什么是数据合成2.2 为什么需要数据合成2.3 10亿种人…

【Datawhale AI夏令营第四期】 浪潮源大模型应用开发方向笔记 Task04 RAG模型 人话八股文Bakwaan_Buddy项目创空间部署

【Datawhale AI夏令营第四期】 浪潮源大模型应用开发方向笔记 Task04 RAG模型 人话八股文Bakwaan_Buddy项目创空间部署 什么是RAG&#xff1a; 我能把这个过程理解为Kimi.ai每次都能列出的一大堆网页参考资料吗&#xff1f;Kimi学了这些资料以后&#xff0c;根据这里面的信息综…

支持2.4G频秒变符合GB42590的标准的飞行器【无人机GB42590发射端】

使用方法: 放在飞机 上&#xff0c;按键那一面需要朝上对着天空(因为GPS陶瓷天线在按键面)&#xff0c;支持基本ID&#xff0c;向量和系统包&#xff0c;电池容量240mAH充电1小时&#xff0c;使用时间大概2小时。 1.长按3秒开关机 2.开机红灯慢闪&#xff0c;只发射基本ID数据…

Spring核心思想讲解之控制反转(IOC)

控制反转概述 控制反转实现方式 XML方式 方式一 方式二 方式三 注解方式 第一步 第二步 第三步 依赖注入&#xff08;DI&#xff09;实现方式 XML方式 手动注入 set注入 构造器注入 自动注入 set注入 构造方法注入 注解方式 方式一&#xff1a; 方式二&…

IO流【详解】

一、IO流 1.1 IO说明 Input 输入 Output 输出 流: 例如水流,流量,即流是指数据流动传输 IO流就是指数据的输入输出 例如: 将磁盘中的小说.txt,读取到java代码中 ---> 输入 例如: 从java代码中,写到磁盘中创建出文件,并向文件中写入内容 --> 输出 1.2 IO体系 IO 字节…

新手也能快速上手!免费的四款视频剪辑神器大揭秘

现在好用的剪辑工具好的的呀&#xff0c;只要有玩抖音、快手和一些视频为主的社交平台&#xff0c;大家都会尝试用一些剪辑工具自己动手剪辑&#xff0c;在近几年视频的热度之下这类工具做得也越来越专业了&#xff0c;当然其中也还是会有既专业又免费实用的产品&#xff0c;今…

教程:一步步教你构建基于Python Flask和Vue的智慧书析K-means分析系统

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

20240821给飞凌OK3588-C的核心板刷Rockchip原厂的Buildroot并挂载1TB的exFAT格式的TF卡

fdisk -l df -h df -t df -T mount 20240821给飞凌OK3588-C的核心板刷Rockchip原厂的Buildroot并挂载1TB的exFAT格式的TF卡 2024/8/21 18:06 【切记&#xff0c;对于Rockchip原厂的Buildroot&#xff0c;如果你没有针对性的适配DTS&#xff1a;修改其中的GPIO口供电&#xff0c…

分析AAC raw data

分析AAC raw data 本文的主要目标是分析说明AAC解码器如何处理RAW AAC数据。通过拆解理解AAC解码器处理raw aac的关键点&#xff0c;通过数据分析和代码阅读&#xff0c;来说明这个细节&#xff0c;某些细微之处尚需深入探索&#xff0c;留待后续更为详尽的阐述。 几种格式介…

C语言 ——— 常见的动态内存错误(上篇)

对NULL指针的解引用操作 代码演示&#xff1a; int* ptr (int*)malloc(sizeof(int) * INT_MAX); *ptr 10; free(ptr); 代码解析&#xff1a; 使用 malloc 函数动态开辟 sizeof(int)*INT_MAX 这么多个字节的空间&#xff0c;而 INT_MAX 是整型类型的最大值&#xff0c;那么…

优化WAN流量:如何通过调整系统设置降低企业网络成本

一、症状与问题背景 当电脑显示空闲状态时&#xff0c;如果满足以下条件&#xff0c;第二拨号链接可能会意外激活&#xff1a; 您正在使用基于 Microsoft Windows 的计算机&#xff0c;该计算机连接到远程网络并且是 Active Directory 域服务 (AD DS) 域的成员。 您通过二级…

jpg怎么转换成pdf?6个简单方法,实现jpg转换成pdf

你是否也曾想将jpg图片转换为pdf格式文档呢&#xff1f;亦或者在处理文档或制作报告时&#xff0c;不知道怎么才能更快地将多张图片整合成一个pdf文件呢&#xff1f;如果你正在寻找简单快速的方法&#xff0c;又有哪些工具可以帮助您完成图片转pdf呢&#xff1f;别着急&#xf…