【C++】vector的使用和模拟实现(超级详解!!!!)

文章目录

  • 前言
  • 1.vector的介绍及使用
    • 1.1 vector的介绍
    • 1.2 vector的使用
      • 1.2.1 vector的定义
      • 1.2.2 vector iterator 的使用
      • 1.2.3 vector 空间增长问题
      • 1.2.3 vector 增删查改
      • 1.2.4 vector 迭代器失效问题。(重点!!!!!!)
      • 1.2.5 vector 在OJ中有关的练习题
  • 2.vector深度剖析及模拟实现
    • 2.1 std::vector的核心框架接口的模拟实现dzj::vector
  • 本文章内容后续会完善一些!!!
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

C++中的vector是一个强大而灵活的动态数组容器,它提供了在运行时动态增长和收缩的能力,极大地简化了数组的管理。vector是标准模板库(STL)中的一部分,为程序员提供了高效的数据存储和操作方式。在本博客中,我们将深入介绍vector的基本用法,并进行深度剖析和模拟实现,以帮助你更好地理解和利用这一重要的C++容器。


提示:以下是本篇文章正文内容,下面案例可供参考

1.vector的介绍及使用

1.1 vector的介绍

vector文档介绍

vector是一个动态数组容器,它以模板类的形式实现,能够存储同一类型的元素。其最显著的特点之一是能够在运行时动态调整数组大小,而不需要手动管理内存。通过push_back()进行元素的追加、pop_back()进行末尾元素的删除,以及使用迭代器进行元素的遍历,vector提供了简单而强大的操作方式。
vector的内部实现采用动态数组,这意味着它能够在需要时自动分配更多的内存空间,以适应元素的增加。这种机制确保了vector的高效性,使得它适用于各种规模和类型的数据集。

参考文献:
Josuttis, N. M. (2007). The C++ Standard Library: A Tutorial and Reference (2nd Edition). Addison-Wesley.
Stroustrup, B. (2013). The C++ Programming Language (4th Edition). Addison-Wesley.
Meyers, S. (2001). Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library. Addison-Wesley.

1.2 vector的使用

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

1.2.1 vector的定义

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v1;//无参构造v1.push_back(0);v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.push_back(6);for (int i = 0; i < v1.size(); i++){cout << v1[i] << " ";}cout << endl;vector<int> v2(v1);v2.push_back(8);v2.push_back(8);v2.push_back(8);for (int i = 0; i < v2.size(); i++){cout << v2[i] << " ";}cout << endl;return 0;
}

1.2.2 vector iterator 的使用

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

#include <iostream>
#include <vector>
using namespace std;
void Print1(const vector<int>&v)//正向遍历
{vector<int>::const_iterator it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;
}
void Print2(const vector<int>& v)//反向遍历
{vector<int>::const_reverse_iterator it = v.rbegin();while (it != v.rend()){cout << *it << " ";it++;}cout << endl;
}
int main()
{vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(5);v1.push_back(6);Print1(v1);Print2(v1);// 使用迭代器进行修改vector<int>::iterator it = v1.begin();while (it != v1.end()){*it *= 2;it++;}Print1(v1);Print2(v1);return 0;
}

1.2.3 vector 空间增长问题

在这里插入图片描述

  1. capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。
    这个问题经常会考察,不要固化的认为,顺序表增容都是2倍,具体增长多少是根据具体的需求定义
    的。vs是PJ版本STL,g++是SGI版本STL。

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

  3. resize在开空间的同时还会进行初始化,影响size。


// vector::capacity
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v;cout << "making v growing!!!!" << endl;cout << "capacity changed:" << v.capacity() << endl;for (int i = 0; i < 100; i++){v.push_back(i);if (v.size() == v.capacity())cout << "capacity changed:" << v.capacity() << endl;}return 0;
}

运行结果:
在这里插入图片描述

// vector::reserve
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v;for (int i = 0; i < 100; i++){v.push_back(i);}cout << "size:" << v.size()<<endl;cout << "capacity:" << v.capacity()<<endl;v.reserve(200);cout << "size:" << v.size() << endl;cout << "capacity:" << v.capacity() << endl;return 0;
}

运行结果:
在这里插入图片描述

// vector::resize
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v;//for (int i = 0; i < 100; i++)//{//	v.push_back(i);//}cout << "size:" << v.size()<<endl;cout << "capacity:" << v.capacity()<<endl;v.resize(200);cout << "size:" << v.size() << endl;cout << "capacity:" << v.capacity() << endl;v.resize(100);cout << "size:" << v.size() << endl;cout << "capacity:" << v.capacity() << endl;v.resize(101,8);cout << "size:" << v.size() << endl;cout << "capacity:" << v.capacity() << endl;for (auto e : v){cout << e << " ";}return 0;
}

运行结果:
在这里插入图片描述

1.2.3 vector 增删查改

在这里插入图片描述

// push_back/pop_back
#include <iostream>
#include <vector>
using namespace std;
int main()
{int arr[] = { 1,2,3,4 };vector<int> v(arr, arr + sizeof(arr) / sizeof(arr[0]));v.push_back(5);v.push_back(6);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++;}return 0;
}
// push_back/pop_back

运行结果:
在这里插入图片描述

// find / insert / erase
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);vector<int>::iterator pos = find(v.begin(), v.end(), 3);v.insert(pos, 0);for (auto e : v){cout << e << " ";}cout << endl;pos = find(v.begin(), v.end(), 3);v.erase(pos);for (auto e : v){cout << e << " ";}return 0;
}

运行结果:
在这里插入图片描述

// operator[]+index 和 C++11中vector的新式for+auto的遍历
// vector使用这两种遍历方式是比较便捷的。
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v = { 1,2,3,4 };//operator[]+indexfor (int i = 0; i < v.size(); i++){cout << v[i]<<" ";}cout << endl;for (int i = 0; i < v.size(); i++){v[i] *= 2;}vector<int> swapv;swapv.swap(v);for (auto e : swapv){cout << e << " ";}return 0;
}

运行结果:
在这里插入图片描述

1.2.4 vector 迭代器失效问题。(重点!!!)

迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了所谓的封装,比如:vector的迭代器就是原生态指针T*。因此迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃(即如果继续使用已经失效的迭代器,程序可能会崩溃)。

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

  1. 会引起其底层空间改变的操作,都有可能是迭代器失效,比如:resize、reserve、insert、assign、
    push_back等。
#include <iostream>
#include <vector>
using namespace std;
int main()
{vector<int> v = { 1,2,3,4 };auto it = v.begin();while (it != v.end()){cout << *it << " ";++it;}v.reserve(100);while (it != v.end()){cout << *it << " ";++it;}return 0;
}

运行错误:
在这里插入图片描述
出错原因:以上操作,都有可能会导致vector扩容,也就是说vector底层原理旧空间被释放掉,而在打印时,it还使用的是释放之间的旧空间,在对it迭代器操作时,实际操作的是一块已经被释放的空间,而引起代码运行时崩溃。
解决方式:在以上操作完成之后,如果想要继续通过迭代器操作vector中的元素,只需给it重新赋值即可。

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

#include <iostream>
using namespace std;
#include <vector>
int main()
{int a[] = { 1, 2, 3, 4 };vector<int> v(a, a + sizeof(a) / sizeof(int));// 使用find查找3所在位置的iteratorvector<int>::iterator pos = find(v.begin(), v.end(), 3);// 删除pos位置的数据,导致pos迭代器失效。v.erase(pos);cout << *pos << endl; // 此处会导致非法访问return 0;
}

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

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

1.2.5 vector 在OJ中有关的练习题

  1. 只出现一次的数字i
  2. 杨辉三角OJ
  3. 删除排序数组中的重复项 OJ
  4. 只出现一次的数ii OJ
  5. 只出现一次的数iii OJ
  6. 数组中出现次数超过一半的数字 OJ
  7. 电话号码字母组合OJ
  8. 连续子数组的最大和 OJ

2.vector深度剖析及模拟实现

在这里插入图片描述

2.1 std::vector的核心框架接口的模拟实现dzj::vector

模拟实现代码

本文章内容后续会完善一些!!!

总结

通过本文的阅读,我们详细了解了C++中vector的基本概念、使用方法和一些关键特性。从动态数组的角度深度剖析了vector的内部机制,以及通过模拟实现进一步加深了对其工作原理的理解。vector的灵活性和高效性使其成为C++编程中不可或缺的工具,无论是在简单的数组操作还是复杂的数据结构中,都能展现其强大的应用价值。通过学习和研究vector,我们能够更好地优化代码、提高程序的效率,为C++编程带来更多便利。希望本文对你在使用和理解C++中的vector时有所帮助。

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

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

相关文章

C++入门和基础

目录 文章目录 前言 一、C关键字 二、命名空间 2.1 命名空间的定义 2.2 命名空间的使用 2.3 标准命名空间 三、C输入&输出 四、缺省参数 4.1 缺省参数的概念 4.2 缺省参数的分类 五、函数重载 5.1 函数重载的简介 5.2 函数重载的分类 六、引用 6.1 引用的…

搭建个人IC_EDA服务器(物理机)一:安装Centos7

1.准备 大于8G的U盘&#xff1b;待装的电脑&#xff0c;我使用淘汰的在大学时候使用的笔记本&#xff1b;U盘启动器制作工具&#xff1a;UltralSo&#xff1b;官网下载的在没有付费的情况下&#xff0c;即使试用期&#xff0c;安装的时候会有莫名的问题&#xff0c;建议使用这…

【接口测试】常见HTTP面试题

目录 HTTP GET 和 POST 的区别 GET 和 POST 方法都是安全和幂等的吗 接口幂等实现方式 说说 post 请求的几种参数格式是什么样的&#xff1f; HTTP特性 HTTP&#xff08;1.1&#xff09; 的优点有哪些&#xff1f; HTTP&#xff08;1.1&#xff09; 的缺点有哪些&#x…

Puzzles

题目链接&#xff1a;Submit - Codeforces​​​​​​ 解题思路&#xff1a; 题目大概意思就是在一个数组里找n个数里的最大值减最小值的最小值&#xff0c;先排序&#xff0c;然后将第i n - 1项减去第i项与最小值作比较&#xff0c;输出最小值即可&#xff0c;注意循环结束…

YOLOv应用开发与实现

一、背景与简介 YOLO&#xff08;You Only Look Once&#xff09;是一种流行的实时目标检测系统&#xff0c;其核心思想是将目标检测视为回归问题&#xff0c;从而可以在单个网络中进行端到端的训练。YOLOv作为该系列的最新版本&#xff0c;带来了更高的检测精度和更快的处理速…

【框架】MyBatis 框架重点解析

MyBatis 框架重点解析 1. MyBatis 执行流程 会话工厂生产的 SqlSession 对象提供了对数据库执行SQL命令所需的所有方法&#xff0c;包括但不限于以下功能&#xff1a; 数据库操作&#xff1a;SqlSession可以执行查询&#xff08;select&#xff09;、插入&#xff08;insert&a…

腾讯云幻兽帕鲁游戏存档迁移教程,本地单人房迁移/四人世界怎么迁移存档?

腾讯云幻兽帕鲁游戏存档迁移的方法主要包括以下几个步骤&#xff1a; 登录轻量云控制台&#xff1a;首先&#xff0c;需要登录到轻量云控制台&#xff0c;这是进行存档迁移的前提条件。在轻量云控制台中&#xff0c;可以找到接收存档的服务器卡片&#xff0c;并点击进入实例详情…

Jmeter 安装

JMeter是Java的框架&#xff0c;因此在安装Jmeter前需要先安装JDK&#xff0c;此处安装以Windows版为例 1. 安装jdk&#xff1a;Java Downloads | Oracle 安装完成后设置环境变量 将环境变量JAVA_HOME设置为 C:\Program Files\Java\jdk1.7.0_25 在系统变量Path中添加 C:\Pro…

股票技术指标(包含贪婪指数)

股票技术指标是用于分析股票价格和成交量数据&#xff0c;以便预测未来市场走势的工具。技术分析师使用这些指标来识别市场趋势、价格模式、交易信号和投资机会。技术指标通常基于数学公式&#xff0c;并通常在股票价格图表上以图形形式表示。 技术指标主要分为以下几类&#x…

A Brief Introduction of the Tqdm Module in Python

DateAuthorVersionNote2024.02.28Dog TaoV1.0Release the note. 文章目录 A Brief Introduction of the Tqdm Module in PythonIntroductionKey FeaturesInstallation Usage ExamplesBasic UsageAdvanced Usage A Brief Introduction of the Tqdm Module in Python Introducti…

力扣hot100:42.接雨水

什么时候能用双指针&#xff1f; &#xff08;1&#xff09;对撞指针&#xff1a; ①两数和问题中可以使用双指针&#xff0c;先将两数和升序排序&#xff0c;可以发现规律&#xff0c;如果当前两数和大于target&#xff0c;则右指针向左走。 ②接雨水问题中&#xff0c;左边最…

【算法集训】基础算法:枚举

一、基本理解 枚举的概念就是把满足题目条件的所有情况都列举出来&#xff0c;然后一一判定&#xff0c;找到最优解的过程。 枚举虽然看起来麻烦&#xff0c;但是有时效率上比排序高&#xff0c;也是一个不错的方法、 二、最值问题 1、两个数的最值问题 两个数的最小值&…

Vscode安装,ssh插件与配置

原因 发现很多新人在练习linux&#xff0c;可是只有windows机的时候&#xff0c;一般都是下载虚拟机&#xff0c;然后在虚拟机上安装ubuntu等linux平台。每次需要在linux中写代码&#xff0c;就打开ubuntu&#xff0c;然后在终端上用vim写代码&#xff0c;或者先编辑代码文本&…

css实现上下左右居中

css实现子盒子在父级盒子中上下左右居中 几种常用的上下左右居中方式 HTML代码部分 <div class"box"><img src"./img/77.jpeg" alt"" class"img"> </div>css部分 方式一 利用子绝父相和margin:auto实现 <sty…

内存管理 -----分段分页

分段 分段&#xff1a;程序的分段地址空间&#xff0c;分段寻址方案 两个问题 分段 &#xff1a;是更好分离和共享 左边是有序的逻辑地址&#xff0c;右边是无序的物理地址&#xff0c;然后需要有一种映射的关系&#xff08;段关联机制&#xff09; 各个程序的分配相应的地址…

Gin入门指南:从零开始快速掌握Go Web框架Gin

官网:https://gin-gonic.com/ GitHub:https://github.com/gin-gonic 了解 Gin Gin 是一个使用 Go 语言开发的 Web 框架,它非常轻量级且具有高性能。Gin 提供了快速构建 Web 应用程序所需的基本功能和丰富的中间件支持。 以下是 Gin 框架的一些特点和功能: 快速而高效:…

Sora模型风口,普通人如何抓住-最新AI系统ChatGPT网站源码,AI绘画系统

一、前言说明 PandaAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持…

边缘计算与任务卸载基础知识

目录 边缘计算简介任务卸载简介参考文献 边缘计算简介 边缘计算是指利用靠近数据生成的网络边缘侧的设备&#xff08;如移动设备、基站、边缘服务器、边缘云等&#xff09;的计算能力和存储能力&#xff0c;使得数据和任务能够就近得到处理和执行。 一个典型的边缘计算系统为…

前端按钮动画

效果示例 代码示例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevic…

OSCP靶场--Resourced

OSCP靶场–Resourced 考点(1.rpc枚举 2.crackmapexec密码喷洒&#xff0c;hash喷洒 3.ntds.dit system提取域hash 4.基于资源的约束委派攻击rbcd) 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC -p- 192.168.188.175 --min-rate 2000 Starting Nmap 7.9…