当前位置: 首页 > 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;他们在机器人领域…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...