vector使用和模拟实现

💓博主个人主页:不是笨小孩👀
⏩专栏分类:数据结构与算法👀 C++👀 刷题专栏👀 C语言👀
🚚代码仓库:笨小孩的代码库👀
⏩社区:不是笨小孩👀
🌹欢迎大家三连关注,一起学习,一起进步!!💓

在这里插入图片描述

vector

  • STL
  • vector的使用
    • 构造函数
    • 迭代器(iterator)
    • resize和reserve
    • 插入删除数据
    • swap
  • vector的模拟实现

STL

什么是STL?

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。

STL的六大组件

在这里插入图片描述

vector的使用

vector就是我们经常说的顺序表,它是库里面已经实现好的,我们可以直接使用,但是需要包一个vector的头文件。它和string有很大的相似性,所以简单的就不说了。

构造函数

在这里插入图片描述

从构造函数我们可以看到,我们可以用n个val来初始化,或者一段迭代器区间,或者一个vector,都是可以的。

void test()
{vector<int> v(10, 1);vector<int> v1(v);vector<int> v2(v1.begin(),v.end());
}

迭代器(iterator)

在这里插入图片描述
我们遍历vector可以用迭代器遍历。如果要倒着遍历的话,就需要用rbegin和rend,下面带c的都是const版本的,不可修改。

void test()
{vector<int> v;vector<int>::iterator it = v.begin();while (it != v.end()){cout << *it << " ";it++;}cout << endl;
}

在这里插入图片描述
它也实现了[]的运算符重载,也可以用for循环像数组一样访问。

void test()
{vector<int> v;for (int i = 0; i < v.size(); i++){cout << v[i] << " ";}
}

resize和reserve

resize还是改变size的大小,reserve还是改变capacity的大小。

在这里插入图片描述
resize的n如果比size要小的话,就是充当删除的功能。
在这里插入图片描述

void test()
{vector<int> v;v.reserve(400);v.resize(10, 2);v.resize(5);
}

插入删除数据

在这里插入图片描述

  1. push_back
    在这里插入图片描述

尾插一个数据

void test()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);
}
  1. pop_back
    在这里插入图片描述

尾删一个数据。

void test()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.pop_back();v.pop_back();v.pop_back();
}
  1. insert

在某个位置插入一个数据,或这n个数据。

在这里插入图片描述
我们可以看到,insert需要我们传迭代器过去,并且返回一个迭代器,返回的这个迭代器就是你插入的那个位置的值的迭代器。

void test()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.insert(v.begin(), 10, 0);v.insert(v.begin(), 0);for (int i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;
}
  1. erase

删除一个数据,或者一段迭代器区间。

在这里插入图片描述

void test()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.erase(v.begin());v.erase(v.begin(), v.end()-1);for (int i = 0; i < v.size(); i++){cout << v[i] << " ";}cout << endl;
}

swap

交换两个vector

在这里插入图片描述

void test1()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);vector<int> v1;v1.push_back(2);v1.push_back(2);v.swap(v1);}

vector的模拟实现

结构

我们string是用的和顺序表一样的结构,没有用模板模拟实现,但是,vector我们要用模板来模拟实现,而且结构也和前面的大有不同,但是换汤不换药,还是顺序表的原理。

在这里插入图片描述

在这里插入图片描述
我们说迭代器是一种类似指针的东西,但是不一定是指针,我们将T*重命名为iterator,也就是迭代器,可以说我们vector这个结构的成员就是三个迭代器,一个指向开始位置,一个指向有效数据的最后一个的下一个位置,还有一个指向空间的最后。

在这里插入图片描述

我们知道指针是可以相减的,同类型的指针相减就是两个指针数据的个数,所以size=_finish-_start,同理capacity = _end-_start.

那么我们就先来把简单的接口实现一下:

//我们声明成员变量时给了缺省值,所以这里什么都不用写,都会初始化为nullptr,但是必须有这个函数。
vector()
{}
~vector()
{delete[] _start;_start = _finish = _end = nullptr;
}
iterator begin()
{return _start;
}iterator end()
{return _start + size();
}const_iterator cbegin() const
{return _start;
}const_iterator cend() const
{return _start+size();
}size_t size() const
{return _finish - _start;
}size_t capacity() const
{return _end - _start;
}T& operator[](size_t pos)
{assert(pos < size());return _start[pos];
}const T& operator[](size_t pos) const
{assert(pos < size());return _start[pos];
}void swap(vector<T>& v)
{std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_end, v._end);
}

上面的这些接口都很简单,就不细讲了。

  1. reserve和resize

reserve就是扩容逻辑,我们需要先开一个空间,然后把数据拷过去,然后在释放原来的空间,把新的空间给_start即可,然后更新_finish和_end。但是需要注意,我们需要先记录一下之前的size,因为_start修改后,就无法知道以前的_size了。

void reserve(size_t n)
{if (n > capacity()){int sz = size();T* tmp = new T[n];if (_start){for (size_t i = 0; i < size(); i++){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = tmp + sz;_end = tmp + n;}
}

resize还是和string一样,如果修改的size 比之前小的话就是删除,比之前大就是看需不需要扩容,然后插数据就可以了。

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++;}}
}
  1. 插入和删除数据

push_back

和顺序表逻辑一样,直接尾插即可。

void push_back(const T& x)
{if (size() == capacity()){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finish = x;_finish++;
}

pop_back

void pop_back()
{assert(size() > 0);_finish--;
}

insert

insert和之前不同的是,之前传的是下标,现在传的是一个迭代器,并且插入后返回插入那个数据的迭代器,因为我们插入数据后,那个位置的迭代器的内容就别更新了,或者有可能会扩容,扩容后原本的那个迭代器就失效了。所以我们会返回插入的那个数据的迭代器。

iterator insert(iterator pos, const T& x)
{assert(pos >= _start);assert(pos <= _finish);if (size() == capacity()){//防止迭代器失效int len = pos-_start;reserve(capacity() == 0 ? 4 : capacity() * 2);//及时更新pospos = _start + len;}iterator end = _finish;while (end > pos){*(end) = *(end - 1);end--;}*pos = x;_finish++;return pos;
}

erase

还是传一个迭代器,删除这个迭代器位置的数据,同样,这个数据被删除了,同样会是迭代器失效,我们还是会返回一个迭代器,返回的还是这个位置的迭代器,指向被删除的数据的下一个数据。

iterator erase(iterator pos)
{assert(pos >= _start);assert(pos < _finish);iterator begin = pos;while (begin < _finish - 1){*begin = *(begin + 1);begin++;}_finish--;return pos;
}
  1. 构造和赋值重载

我们知道库里面有很多构造,可以用n个val来初始化,也可以用一段迭代器区间,都是一样的思路,直接尾插数据就可以了,但是n个val可以复用resize这个函数。

vector(int n, const T& value = T())
{resize(n, value);
}
template<class InputIterator>
vector(InputIterator first, InputIterator last)
{while (first < last){push_back(*first);first++;}
}
vector(const vector<T>& v)
{reserve(v.capacity());for (auto& e : v){push_back(e);}}

赋值重载
我们直接拷贝构造一份数据,和this交换。

vector<T>& operator= (vector<T> tmp)
{swap(tmp);return *this;
}

今天的分享就到这里吧,感谢大家的关注和支持。

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

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

相关文章

新增MariaDB数据库管理、支持多版本MySQL数据库共存,1Panel开源面板v1.6.0发布

2023年9月18日&#xff0c;现代化、开源的Linux服务器运维管理面板1Panel正式发布v1.6.0版本。 在这个版本中&#xff0c;1Panel新增MariaDB数据库管理&#xff1b;支持多版本MySQL数据库共存&#xff1b;支持定时备份系统快照和应用商店中已安装应用&#xff1b;支持为防火墙…

人脸识别三部曲

人脸识别三部曲 首先看目录结构图像信息采集 采集图片.py模型训练 训练模型.py人脸识别 人脸识别.py效果 首先看目录结构 引用文121本 opencv │ 采集图片.py │ 训练模型.py │ 人脸识别.py │ └───trainer │ │ trainer.yml │ └───data │ └──…

关于时空数据的培训 GAN:实用指南(第 02/3 部分)

一、说明 在本系列关于训练 GAN 实用指南的第 1 部分中&#xff0c;我们讨论了 a&#xff09; 鉴别器 &#xff08;D&#xff09; 和生成器 &#xff08;G&#xff09; 训练之间的不平衡如何导致模式崩溃和由于梯度消失而导致静音学习&#xff0c;以及 b&#xff09; GAN 对超参…

3D模型转换工具HOOPS Exchange如何实现OBJ格式轻量化?

什么是OBJ模型轻量化&#xff1f; OBJ格式是一种常用的三维模型文件格式&#xff0c;通常包含模型的顶点、法线、纹理坐标等信息&#xff0c;但有时候这些信息可能会使模型文件变得较大&#xff0c;不利于网络传输、加载和运行。 OBJ&#xff08;Object&#xff09;模型轻量化…

QTC++ day12

注册登录界面 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QIcon> #include <QPushButton> #include <QLineEdit> #include <QLabel> #include <QDebug> #include <QMessageBox>//消息对话框类 #inc…

算法通过村第九关-二分(中序遍历)黄金笔记|手撕二分

文章目录 前言1. 基本查找2. 二分查找与分治2.1 循环的方式2.2 递归的方式 3. 元素中的重复的二分查找总结 前言 提示&#xff1a;有些人&#xff0c;远看是灯塔&#xff0c;靠近是悬崖。 --任明信《别人》 二分查找是非常重要的算法之一&#xff0c;不仅要掌握&#xff0c;更要…

halcon算子2、gray_histo

gray_histo 计算直方图 原形&#xff1a;gray_histo(Regions, Image : : : AbsoluteHisto, RelativeHisto) 功能&#xff1a;计算直方图 参数&#xff1a;Regions&#xff1a;区域&#xff0c;要计算的区域&#xff08;在image上的区域&#xff09; Image &#xff1a;要计算的…

Postman应用——Variable变量设置(Global、Environment和Collection)

文章目录 Global变量设置Environment变量设置Collection变量设置Global、Environment环境变量预览 Global、Environment和Collection变量使用&#xff0c;点击查看。 Global变量设置 全局变量设置&#xff0c;作用域是所有Collection、Folder和Request&#xff0c;全局变量只有…

Docker网络问题:容器无法访问外部网络

Docker网络问题&#xff1a;容器无法访问外部网络 &#x1f61f; Docker网络问题&#xff1a;容器无法访问外部网络 &#x1f61f;摘要 &#x1f914;引言 &#x1f310;正文 &#x1f913;为什么容器无法访问外部网络&#xff1f; &#x1f615;1. 网络配置错误2. 防火墙设置3…

【智能电表数据接入物联网平台实践】

智能电表数据接入物联网平台实践 设备接线准备设备调试代码实现Modbus TCP Client 读取电表数据读取寄存器数据转成32bit Float格式然后使用modbusTCP Client 读取数据 使用mqtt协议接入物联网平台最终代码实现 设备接线准备 设备调试 代码实现 Modbus TCP Client 读取电表数…

pymysql执行非查询语句会自动提交事务,关闭事务自动提交

一、前置条件 在mysql数据库生成数据&#xff1a; CREATE DATABASE mydatabase;CREATE TABLE Course (CourseID INT PRIMARY KEY,CourseName VARCHAR(100),Instructor VARCHAR(100),Credits INT,StudentID INT,FOREIGN KEY (StudentID) REFERENCES StudentInformation(Studen…

win10 Baichuan2-7B-Chat-4bits 上部署 百川2-7B-对话模型-4bits量化版

搞了两天才搞清楚跑通 好难呢,个人电脑 win10 ,6GB显存 个人感觉 生成速度很慢,数学能力不怎么行 没有ChatGLM2-6B 强,逻辑还行, 要求: 我的部署流程 1.下载模型 ,下载所有文件 然后 放到新建的model目录 https://huggingface.co/baichuan-inc/Baichuan2-7B-Chat-4bits/tr…

HarmonyOS之 组件的使用

一 容器 1.1 容器分类 Column表示沿垂直方向布局的容器。Row表示沿水平方向布局的容器。 1.2 主轴和交叉轴 主轴&#xff1a;在Column容器中的子组件是按照从上到下的垂直方向布局的&#xff0c;其主轴的方向是垂直方向&#xff1b;在Row容器中的组件是按照从左到右的水平方向…

怒刷LeetCode的第11天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;迭代 方法二&#xff1a;递归 方法三&#xff1a;指针转向 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;快慢指针 方法二&#xff1a;Arrays类的sort方法 方法三&#xff1a;计数器 方法四…

如何借助上线初期运维管理守住项目建设最后一公里

随着运营商技术升级、业务发展&#xff0c;以及服务能力要求提升&#xff0c;当下新建项目的交付或系统大版本升级大多数都需要历经千辛万苦才达到上线的彼岸。然而&#xff0c;项目上线并不意味着项目结束&#xff0c;“上线”也并不意味着终点&#xff0c;而是一个新的管理模…

Redis学习笔记--001

Redis快速入门 文章目录 Redis快速入门一、初识Redis1.1、NoSQL数据库1.2、Redis介绍1.3、[Redis](https://redis.io/)的安装 二、Redis常见命令2.1、Redis默认启动2.2、指定配置启动2.3、Redis开机自启设置 三、Redis客户端3.1、Redis命令行客户端3.2、图形化桌面客户端 四、r…

软件项目开发的流程及关键点

软件项目开发的流程及关键点 graph LR A[需求分析] --> B[系统设计] B --> C[编码开发] C --> D[测试验证] D --> E[部署上线] E --> F[运维支持]在项目开发的流程中&#xff0c;首先是进行需求分析&#xff0c;明确项目的目标和功能要求。接下来是系统设计&am…

【Vue.js】vue-cli搭建SPA项目并实现路由与嵌套路由---详细讲解

一&#xff0c;何为SPA SPA&#xff08;Single Page Application&#xff09;是一种 Web 应用程序的开发模式&#xff0c;它通过使用 AJAX 技术从服务器异步加载数据&#xff0c;动态地更新页面内容&#xff0c;实现在同一个页面内切换不同的视图&#xff0c;而无需整页刷新 1.…

优维低代码实践:图片和搜索

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

爬虫 — App 爬虫(一)

目录 一、介绍二、APP 爬虫常见反爬三、APP 抓包常用工具四、模拟器五、安装 APP1、下载 APP2、安装 APP 六、fiddler1、工作原理2、安装3、基本介绍 七、环境配置1、fiddler 的配置2、夜神模拟器的配置 八、案例 一、介绍 爬虫分类——数据来源 1、PC 端爬虫&#xff08;网页…