【C++】vector的简单使用和实现

news2025/2/3 22:04:39

vector就是我们之前数据结构学的顺序表,这篇博客就是说一说它的简单使用底层实现

文章目录

  • 简单使用
  • 模拟实现

简单使用

首先,我们看看它的构造函数
在这里插入图片描述
我们比较常用的也就是第二种,就是第一个参数是要存的数据个数,第二个是要填充的数据

	vector<int>f(10, 0);

这个的意思就是表中存放十个数据,每个数据是0

    vector<int>g;

这种就是创建一个空的vector表,也就对应上面第一种情况
除了这两种,第三种情况可以看到是一个模板,这个模板实例化后可以是迭代器,也就是用迭代器区间去构造,当然如果是数组也可以,因为它的底层空间是连续的

int main() {
	vector<int>f(10, 0);
	vector<int>g(f.begin(), f.end());
	for (auto e : g) {
		cout << e << ' ';
	}
	cout << endl;

	string s1("abcdefg");
	vector<char>s2(s1.begin(), s1.end());
	for (auto e : s2) {
		cout << e << ' ';
	}
	cout << endl;
	return 0;
}
char s1[] = "abcdefg";
	vector<char>s2(s1,s1+6);
	for (auto e : s2) {
		cout << e << ' ';
	}
	cout << endl;

这里就是分别用迭代器数组名(指针)初始化的。
跟string一样,vector的数据访问也可以用方括号,迭代器和范围for

int main() {
	vector<int>f;
	f.push_back(1);
	f.push_back(2);
	f.push_back(3);
	f.push_back(4);
	f.push_back(5);
	for (size_t i = 0; i < f.size(); i++) {
		cout << f[i] << ' ';
	}
	cout << endl;
	vector<int>::iterator it = f.begin();
	while (it != f.end()) {
		cout << *it << ' ';
		it++;
	}
	cout << endl;
	for (auto e : f) {
		cout << e << ' ';
	}
	cout << endl;
	return 0;
}

我们这里插入函数传位置的话只能传迭代器,我们可以先查找一下,查找就用算法里的find
在这里插入图片描述
要包含算法的头文件
在这里插入图片描述

int main() {
	vector<int>f;
	f.push_back(1);
	f.push_back(2);
	f.push_back(3);
	f.push_back(4);
	f.push_back(5);
	vector<int>::iterator it = find(f.begin(), f.end(), 3);
	f.insert(it, 30);
	for (auto e : f) {
		cout << e << ' ';
	}
	cout << endl;
}

模拟实现

#include<assert.h>
namespace jxh {
	template<class T>
	class vector {
	public:
		typedef T* iterator;
		typedef const T* const_iterator;
		vector() {};
		vector(const vector<T>& v) {
			reserve(v.capacity());
			for (const auto& e : v) {
				push_back(e);
			}
		}
		template <class InputIterator>
		vector(InputIterator first, InputIterator last) {
			while (first != last) {
				push_back(*first);
				++first;
			}
		}
		vector(size_t n, const T& val = T()) {
			resize(n, val);
		}
		vector(int n, const T& val = T()) {
			resize(n, val);
		}
		void swap(vector<T>& v) {
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_endofstorage, v._endofstorage);
		}
		vector<T>& operator=(vector<T>v) {
			swap(v);
			return *this;
		}
		~vector() {
			if (_start) {
				delete[]_start;
				_start = _finish = _endofstorage = nullptr;
			}
		}
		iterator begin() {
			return _start;
		}
		iterator end() {
			return _finish;
		}
		const_iterator begin()const {
			return _start;
		}
		const_iterator end()const {
			return _finish;
		}
		size_t size()const {
			return _finish - _start;
		}
		size_t capacity()const {
			return _endofstorage - _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 reserve(size_t n) {
			if (n > capacity()) {
				size_t old = size();
				T* tmp = new T[n];
				if (_start) {
					for (size_t i = 0; i < old; i++) {
						tmp[i] = _start[i];
					}
					delete[]_start;
				}
				_start = tmp;
				_finish = _start + old;
				_endofstorage = _start + n;
			}
		}
		void resize(size_t n, T val = T()) {
			if (n > size()) {
				reserve(n);
				while (_finish < _start + n) {
					*_finish = val;
					++_finish;
				}
			}
			else {
				_finish = _start + n;
			}
		}
		void push_back(const T& x) {
			if (_finish == _endofstorage) {
				size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
				reserve(newcapacity);
			}
			*_finish = x;
			++_finish;
		}
		void pop_back() {
			assert(size() > 0);
			--_finish;
		}
		iterator insert(iterator pos, const T& x) {
			assert(pos >= _start && pos <= _finish);
			if (_finish == _endofstorage) {
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : capacity() * 2);
				pos = _start + len;
			}
			iterator end = _finish - 1;
			while (end >= pos) {
				*(end + 1) = *end;
				--end;
			}
			*pos = x;
			++_finish;
			return pos;
		}
		iterator erase(iterator pos) {
			assert(pos >= _start && pos < _finish);
			iterator it = pos + 1;
			while (it < _finish) {
				*(it - 1) = *it;
				++it;
			}
			_finish--;
			return pos;
		}

	private:
		iterator _start = nullptr;
		iterator _finish = nullptr;
		iterator _endofstorage = nullptr;
	};
	void print_vector(const vector<int>& v) {
		for (auto e : v) {
			cout << e << " ";
		}
		cout << endl;
	}
}

STL源码中,vector的实现不是像我们之前用一个指针,一个size,一个capacity实现的,而是用三个指针,用指针之间的减法来算出size和capacity

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

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

相关文章

Linux系统Shell脚本-----------正则表达式 文本三剑客之---------grep、 sed

一、正则表达式 1.前言 正则表达式(regular expression)描述了一种字符串匹配的模式&#xff08;pattern&#xff09;&#xff0c;可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。在Linux中也就是代表我们定义的模式模板&…

HAL库硬件SPI点亮板载LCD屏幕

1、本节内容介绍 1.1、HAL库硬件SPI 在cubemx中的配置及注意事项; 1.2、HAL库SPI详解与结构介绍; 1.3、实现硬件SPI驱动板载ST7789显示屏,240*240像素&#xff1b; 源码地址&#xff1a;https://gitee.com/MR_Wyf/hal-cubemx-rt-thread/tree/hal_rttNano_st7789_menu/ 或者…

多线程互斥量进阶

问题 一个线程多次尝试获取同一个互斥量&#xff0c;会发生什么&#xff1f; 不同类型的互斥量 Linux 上的示例程序 死锁的概念 等待关系 线程所需资源被其他线程所持有&#xff0c;进而必须等待 (无法继续执行) 循环等待 当线程之间出现循环等待关系时&#xff0c;即&…

2024美赛MCM Problem A: Resource Availability and Sex Ratios资源可用性和性别比例 完整代码以及思路分享

虽然一些动物物种存在于通常的雄性或雌性性别之外&#xff0c;但大多数物种实质上是雄性或雌性。虽然许多物种在出生时的性别比例为1&#xff1a;1&#xff0c;但其他物种的性别比例并不均匀。这被称为适应性性别比例的变化。例如&#xff0c;美洲短吻鳄孵化卵的巢穴的温度会影…

RIP——路由信息协议

目录 1 内部网关协议 RIP 1.1 协议 RIP 的工作原理 1.2 RIP“距离”的定义 1.3 RIP 协议的三个特点 1.4 RIP 协议的优缺点 1.5 路由表的建立 路由表主要信息和更新规则 2 距离向量算法 3 RIP2 报文 4 坏消息传播得慢 5 启动RIP 启动RIP: router rip 命令 启用和检…

TCP 连接掉线自动重连

文章目录 TCP 连接掉线自动重连定义使用连接效果 TCP 接收数据时防止掉线。TCP 连接掉线自动重连。多线程环境下TCP掉线自动重连。 欢迎讨论更好的方法&#xff01; TCP 连接掉线自动重连 定义 定义一个类&#xff0c;以编写TCP连接函数Connect()&#xff0c;并且&#xff1a…

vue-3d-loader

vue-3d-loader - npm GitHub - king2088/vue-3d-loader: VueJS and threeJS 3d viewer 是对 vue-3d-model 的改进&#xff0c;降低Threejs使用难度 # 默认安装 "vue-3d-loader": "^1.3.4", 只支持vue2 npm i vue-3d-loader # vue3 需要安装2版本&#xf…

2024美赛 MCMProblem B: Searching for Submersibles 问题B 搜索潜水器 完整思路代码分享

总部位于希腊的小型海上巡航潜艇&#xff08;MCMS&#xff09;公司&#xff0c;制造能够将人类运送到海洋最深处的潜水器。潜水器被移动到该位置&#xff0c;并不受主船的束缚。MCMS现在希望用他们的潜水器带游客在爱奥尼亚海底探险&#xff0c;寻找沉船。然而&#xff0c;在他…

homeword_day1

第一章 命名空间 一&#xff0e;选择题 1、编写C程序一般需经过的几个步骤依次是&#xff08; B &#xff09; A. 编辑、调试、编译、连接 B. 编辑、编译、连接、运行 C. 编译、调试、编辑、连接 D. 编译、编辑、连接、运行 2、所谓数据封装就是将一组数据和与这组数据…

Servlet简述

Servlet是动态web资源开发技术&#xff0c;其实就是一个接口&#xff0c;将来定义Servlet实现类时&#xff0c;都必须实现该接口&#xff0c;并让web服务器运行Servlet 1.快速入门 使用注释配置访问路径在Servlet3.0之后应用&#xff0c;在此之前都是使用xml配置文件来配置的。…

推荐一款Linux、数据库、Redis、MongoDB统一管理平台!

官方演示 状态查看 ssh 终端 文件操作 数据库操作 sql 编辑器 在线增删改查数据 Redis 操作 Mongo 操作 系统管理 账号管理 角色管理 资源管理 一.安装 1.下载安装包 cd /opt wget https://gitee.com/dromara/mayfly-go/releases/download/v1.7.1/mayfly-go-linux-amd64.zi…

Ruoyi-Cloud-Plus_Nacos配置服务漏洞CVE-2021-29441_官方解决方法以及_修改源码解决---SpringCloud工作笔记199

CVE-2021-29441 这个漏洞是Nacos的,通过使用postman,直接访问接口: 就可以直接添加nacos的用户 Nacos是Alibaba的一个动态服务发现、配置和服务管理平台。攻击者通过添加Nacos-Server的User-Agent头部将可绕过(nacos.core.auth.enabled=true)鉴权认证,从而进行API操作。 …

深度解析 Netty 架构与原理

一共 28661字&#xff0c;耐心看完。 在阅读本文前最好有 Java 的 IO 编程经验&#xff08;知道 Java 的各种 IO 流&#xff09;&#xff0c;以及 Java 网络编程经验&#xff08;用 ServerSocket 和 Socket 写过 demo&#xff09;&#xff0c;并对 Java NIO 有基本的认识&…

状态压缩 笔记

棋盘式的f[i][j]中表示状态的j可以是状态本身也可以是在合法状态state中的下标 用状态本身比较方便&#xff0c;用下标比较省空间 用下标的话可以开id[M]数组记录一下 蒙德里安的梦想 求把 NM的棋盘分割成若干个 12的长方形&#xff0c;有多少种方案。 例如当 N2&#xff0…

Camunda 流程引擎API介绍

&#x1f496;专栏简介 ✔️本专栏将从Camunda(卡蒙达) 7中的关键概念到实现中国式工作流相关功能。 ✔️文章中只包含演示核心代码及测试数据&#xff0c;完整代码可查看作者的开源项目snail-camunda ✔️请给snail-camunda 点颗星吧&#x1f618; &#x1f496;Services …

Map和Set讲解

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 集合框架 模型 Set 常见方法和说明 Set总结 Map说明 Map常见方法和说明 Map 中HashMap的 …

SpringBoot 使用定时任务(SpringTask)

Spring3.0以后自带的task&#xff0c;可以将它看成一个轻量级的Quartz&#xff0c;而且使用起来比Quartz简单许多。 使用步骤&#xff1a; 1.导入坐标 在spring-boot-starter-web坐标中&#xff0c;就包含了SpringTask&#xff0c;所以一般的Web项目都包含了。 <depende…

fastadmin导入excel并对导入数据处理

情景描述 fastadmin有自带的导入功能&#xff0c;但是不好用&#xff0c;它要求你的表格标题必须跟数据表的备注一致&#xff0c;而且拿到的数据是直接插入数据表&#xff0c;我们无法获取想要的数据并对数据进行处理&#xff1b;而且有时候我们只是想要单纯的读取文件功能&…

HTTP中传输协议的数据格式

HTTP 概述&#xff1a;超文本传输协议(Hyper Text Transfer Protocol) 传输协议&#xff1a;定义了客户端和服务器通信时&#xff0c;发送数据的格式 客户端和服务器端交互&#xff1a;客户端向服务器端发送请求&#xff0c;服务器端向客户端响应请求 HTTP特点&#xff1a;…

Aspose.Words简单使用

Aspose.Words简单使用 简介 Aspose.Words for Java 是一个用于处理和操作 Word 文档的强大 Java 库。本文档提供了使用 Maven 在你的 Java 项目中集成和使用 Aspose.Words 的简单步骤。 安装步骤 1. 配置 Aspose Maven 仓库 在你的 pom.xml 文件中添加以下配置&#xff0c…