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

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;
}

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

相关文章:

vector使用和模拟实现

&#x1f493;博主个人主页:不是笨小孩&#x1f440; ⏩专栏分类:数据结构与算法&#x1f440; C&#x1f440; 刷题专栏&#x1f440; C语言&#x1f440; &#x1f69a;代码仓库:笨小孩的代码库&#x1f440; ⏩社区&#xff1a;不是笨小孩&#x1f440; &#x1f339;欢迎大…...

token登录的实现

token登录的实现 我这种token只是简单的实现token&#xff0c;就是后端利用UUID 生成简单随机码&#xff0c;利用随机码作为在Redis中的键&#xff0c;然后存储的用户信息作为值&#xff0c;在每次合理请求的时候对token的有效时间进行刷新&#xff08;利用拦截器&#xff09;&…...

GO语言从入门到实战-Go语言课程介绍

为什么选择 Go 语言来完成这么大一个项目呢&#xff1f;我们不妨回到 Go 语言的源头看一看。 Go 语言的初步设想始于 2007 年&#xff0c;当时 Go 语言的三位创始人是想通过开发一种新型的语言来解决 Google 在软件开发中面临的问题&#xff1a; 多核硬件架构&#xff1b;超大…...

七天学会C语言-第六天(指针)

1.指针变量与普通变量 指针变量与普通变量是C语言中的两种不同类型的变量&#xff0c;它们有一些重要的区别和联系。 普通变量是一种存储数据的容器&#xff0c;可以直接存储和访问数据的值。&#xff1a; int num 10; // 定义一个整数型普通变量num&#xff0c;赋值为10在例…...

2023年腾讯云轻量服务器测评:16核 32G 28M 配置CPU测试

腾讯云轻量应用服务器16核32G28M配置优惠价3468元15个月&#xff08;支持免费续3个月/送同配置3个月&#xff09;&#xff0c;轻量应用服务器具有100%CPU性能&#xff0c;系统盘为380GB SSD盘&#xff0c;28M带宽下载速度3584KB/秒&#xff0c;月流量6000GB&#xff0c;折合每天…...

macos (M2芯片)搭建flutter环境

安装的版本3.13.4、电脑上没有安装过android studio、安装过brew 1.在终端运行sudo softwareupdate --install-rosetta --agree-to-license&#xff0c;下图展示安装成功的效果 2.下载以下安装包来获取最新的 stable Flutter SDK 3.解压&#xff0c;⚠️注意下载安装sdk的包名…...

Xilinx FPGA未使用管脚上下拉状态配置(ISE和Vivado环境)

文章目录 ISE开发环境Vivado开发环境方式1&#xff1a;XDC文件约束方式2&#xff1a;生成选项配置 ISE开发环境 ISE开发环境&#xff0c;可在如下Bit流文件生成选项中配置。 右键点击Generate Programming File&#xff0c;选择Process Properties&#xff0c; 在弹出的窗口选…...

数据结构---链表(java)

目录 1. 链表 2. 创建Node 3. 增加 4. 获取元素 5. 删除 6. 遍历链表 7. 查找元素是否存在 8. 链栈的实现 9. 链队的实现 1. 链表 数据存放在"Node"结点中 优点&#xff1a;不用考虑扩容和缩容的问题&#xff0c;实现了动态存储数据 缺点&#xff1a;没有…...

Qt --- Day02

实现效果&#xff1a; 点击登录&#xff0c;检验用户密码是否正确&#xff0c;正确则弹出消息框&#xff0c;点击ok转到另一个页面 不正确跳出错误消息框&#xff0c;默认选线为Cancel&#xff0c;点击Yes继续登录 点击Cancel跳出问题消息框&#xff0c;默认选项No&#xff0c…...

Redis 集合(Set)快速指南 | Navicat

Redis 支持通过多种数据类型来存储项目集合。其中&#xff0c;包括列表、集合和哈希。上周的博文介绍了列表&#xff08;List&#xff09;数据类型并重点介绍了一些用于管理列表&#xff08;List&#xff09;的主要命令。在今天的文章中&#xff0c;我们将转向关注集合&#xf…...

【华为云云耀云服务器L实例评测】- 云原生实践,快捷部署人才招聘平台容器化技术方案!

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…...

【Java】泛型 之 什么是泛型

什么是泛型 泛型是一种“代码模板”&#xff0c;可以用一套代码套用各种类型。 在讲解什么是泛型之前&#xff0c;我们先观察Java标准库提供的ArrayList&#xff0c;它可以看作“可变长度”的数组&#xff0c;因为用起来比数组更方便。 实际上ArrayList内部就是一个Object[]…...

Python yaml 详解

文章目录 1 概述1.1 特点1.2 导入 2 对象2.1 字典2.2 数组2.3 复合结构 3 操作3.1 读取3.2 写入 1 概述 1.1 特点 yaml 文件是一种数据序列化语言&#xff0c;广泛用于配置文件、日志文件等特点&#xff1a; ① 大小写敏感。② 使用缩进表示层级关系。缩进时不允许使用 Tab 键…...

RabbitMQ消息可靠性(二)-- 消费者消息确认

一、消费者消息确认是什么&#xff1f; 在这种机制下&#xff0c;消费者在接收到消息后&#xff0c;需要向 RabbitMQ 发送确认信息&#xff0c;告知 RabbitMQ 已经接收到该消息&#xff0c;并已经处理完毕。如果 RabbitMQ 没有接收到确认信息&#xff0c;则会将该消息重新加入…...

【python第7课 实例,类】

文章目录 一、实例1.1实例的变量1.2实例方法1.3 构造方法1.4析构函数1.4预置实例属性&#xff1a; 二&#xff0c;类1.1类变量1.2类方法1.3静态方法1.4类属性的增删改查 一、实例 1.1实例的变量 使用示例 class dog:def __init__(self,k,c,a):self.kinds kself.color csel…...

RocketMQ源码解析(上)

一、ACL权限控制 应用场景&#xff1a; ​RocketMQ提供了针对队列、用户等不同维度的非常全面的权限管理机制。通常来说&#xff0c;RocketMQ作为一个内部服务&#xff0c;是不需要进行权限控制的&#xff0c;但是&#xff0c;如果要通过RocketMQ进行跨部门甚至跨公司的合作&…...

Webpack打包CSS文件,解决You may need an appropriate loader to handle this file type报错

在项目文件夹下创建webpack.config.js文件&#xff0c;该文件就是Webpack的配置文件 注意&#xff1a;该文件中遵循Node.js的代码格式规范 &#xff0c;需要对导出配置文件中的内容 Webpack在默认情况下只能打包js文件&#xff0c;如果我们希望他能够打包其他类型的文件&#…...

轮换对称性

二重积分 普通对称性–D关于 y x yx yx对称&#xff1a; ∬ D f ( x , y ) d σ { 2 ∬ D 1 f ( x , y ) d σ f ( x , y ) f ( y , x ) 0 f ( x , y ) − f ( y , x ) \iint_{D}f(x,y)d\sigma\begin{cases} 2\iint_{D_1}f(x,y)d\sigma\ \ \ \ \ \ f(x,y)f(y,x) \\ 0 \ \…...

【MySQL基础】--- 约束

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】&#x1f388; 本专栏旨在分享学习MySQL的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 目录 一、什么…...

ROS2 的行为树 — 第 1 部分:解锁高级机器人决策和控制

一、说明 在复杂而迷人的机器人世界中&#xff0c;行为树&#xff08;BT&#xff09;已成为决策过程中不可或缺的一部分。它们提供了一种结构化、模块化和高效的方法来对机器人的行为进行编程。BT起源于视频游戏行业&#xff0c;用于控制非玩家角色&#xff0c;他们在机器人领域…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...

SQL注入篇-sqlmap的配置和使用

在之前的皮卡丘靶场第五期SQL注入的内容中我们谈到了sqlmap&#xff0c;但是由于很多朋友看不了解命令行格式&#xff0c;所以是纯手动获取数据库信息的 接下来我们就用sqlmap来进行皮卡丘靶场的sql注入学习&#xff0c;链接&#xff1a;https://wwhc.lanzoue.com/ifJY32ybh6vc…...

RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上

一、软件介绍 文末提供程序和源码下载 RushDB 改变了您处理图形数据的方式 — 不需要 Schema&#xff0c;不需要复杂的查询&#xff0c;只需推送数据即可。 二、Key Features ✨ 主要特点 Instant Setup: Be productive in seconds, not days 即时设置 &#xff1a;在几秒钟…...