C++入门 vector部分模拟实现

news2024/12/23 17:24:35

目录

vector大致框架

vector常见接口模拟实现

begin迭代器 & end迭代器

capacity( ) & size( )

reserve

operator[ ]

push_back( ) & pop_back( )

sort


vector大致框架

vector的内部的成员变量大概有三部分构成:

namespace bit
{
	template<class T>
	class vector
	{
	public:
		typedef T* iterator;
		typedef const T* const_iterator;

	private:
		iterator _start = nullptr;              //记录头元素
		iterator _finish = nullptr;             //记录尾元素
		iterator _end_of_storage = nullptr;     //记录容量
	};

这里成员变量的iterator可以理解为指针类型,但实际上并不是指针。具体框架就如上vector所示,这里不难发现,vector利用的是模板,意味着vector可以利用string等类型来搭建顺序表。


vector常见接口模拟实现

既然刚刚解释了iterator,那我们先模拟实现begin迭代器和end迭代器:

begin迭代器 & end迭代器

const_iterator begin() const
{
	return _start;
}

const_iterator end() const
{
	return _finish;
}

iterator begin()
{
	return _start;
}

iterator end()
{
	return _finish;
}

begin直接返回头元素地址,end直接返回尾元素地址。


capacity( ) & size( )

根据上文的三个成员变量,我们可以设计出以下的代码来反映vector的元素个数和容量大小。

size_t capacity()
{
	return _end_of_storage - _start;
}

size_t size()
{
	return _finish - _start;
}

由图可知, end与start相减是元素个数,end of storage与start相减是容量大小。

思考:为什么两个指针相减可以算出元素个数?

答案:指针相减的结果:例如两个整型指针的地址相差8个字节,但是相减的结果为2,是因为两个指针相减操作会对其结果除以该指针所代表的数据类型的字节数,此处整型数据类型有4个字节,所以指针相减结果为2.


reserve

void reserve(size_t n)
{
	if (n > capacity())
	{
		size_t oldsize = size();
		T* tmp = new T[n];

		if (_start)
		{
			memcpy(tmp, _start, sizeof(T) * size());
			delete[] _start;
		}

		_start = tmp;
		_finish = _start + oldsize;
		_end_of_storage = _start + n;
	}
}

思考一下,为什么reserve的空间大于容量大小要开辟空间?如下图所示:

 如果我们直接在原空间扩容,需要计算多扩容的个数,并且无法控制扩容的位置是否连续,对此应对这个问题,我们通过另外开辟一个n大小的空间进行memcpy。


operator[ ]

T& operator[](size_t i)
{
	assert(i < size());

	return _start[i];
}

assert保证了不会越界访问,否则会断言。


push_back( ) & pop_back( )

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

void pop_back()
{
	assert(size() > 0);

	--_finish;
}

pop_back很好理解,尾删只需要把只需要将指向尾元素的指针往前移一位即可。

push_back就稍微麻烦,需要考虑扩容,如果不够需要另外开辟大小为原容量两倍的空间来拷贝原顺序表,并将需要尾插的元素放在finish指向的空间。


sort

另外介绍algorithm头文件中一个算法函数:排序。

具体使用方法如下代码所示:

void test_vector()
{
	vector<int> v1;
	v1.push_back(10);
	v1.push_back(2);
	v1.push_back(30);
	v1.push_back(4);
	v1.push_back(44);
	v1.push_back(4);
	v1.push_back(40);
	v1.push_back(4);

	//sort(v1.begin()+1, v1.end()-1);				//除首尾元素的排序
	//sort(v1.begin(), v1.begin() + v1.size() / 2);	//只排序一半元素

	// 默认是升序
	// 此处为降序
	sort(v1.begin(), v1.end(), greater<int>());
	for (const auto& e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

int main()
{
	test_vector();
	return 0;
}

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

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

相关文章

python字符串如何删除后几位

1、首先在jupyter notebook中新建一个空白的python文件&#xff1a; 2、然后定义一个字符串&#xff0c;用字符串截取的方式打印出排除最后三个字符的结果&#xff0c;这里的“s[:-3]”的意思就是从字符串取第0个字符至倒数第三个字符的前一个字符&#xff0c;这样就截取了最后…

DDP(Differential Dynamic Programming)算法举例

DDP(Differential Dynamic Programming)算法 基本原理 DDP(Differential Dynamic Programming)是一种用于求解非线性最优控制问题的递归算法。它基于动态规划的思想,通过线性化系统的动力学方程和二次近似代价函数,递归地优化控制策略。DDP的核心在于利用局部二次近似来…

昇腾Ascend上使用分布式训练

一、环境搭建 1、使用hccn_tool配置昇腾训练卡的芯片网络&#xff0c;包括ip地址和掩码 命令原型 hccn_tool [-i %d] -ip -s [address %s] [netmask %s] 使用样例(配置两张卡)&#xff1a; hccn_tool -i 0 -ip -s address 192.168.2.10 netmask 255.255.255.0 hccn_tool …

丰臣秀吉-读书笔记六

登山的目标必然是山顶。但人生的乐趣和生息的快乐却不在山顶&#xff0c;相反可以说是在山中的逆境之处。当我们遇上峡谷、绝壁、溪流、断崖、雪崩之类的险路时&#xff0c;心里虽想着已经不行了等&#xff0c;却不甘就此罢手而不与面前的艰难险阻战斗。而当我们完美克服并跨越…

【SpringSecurity】认证与鉴权框架SpringSecurity——认证

目录 SpringSecurity介绍特性CSRF攻击攻击模式攻击原理预防手段 XSS攻击攻击模式危害预防手段 SpringSecurity预防CSRF攻击SpringSecurity预防XSS攻击SpringSecurity与OAuth2的关系SpringSecurity的核心功能 代码实战依赖定义一个接口Redis工具类响应类直接运行工具类认证业务密…

简易智能家居系统

文章目录 摘要一、系统设计要求及总体设计方案1.1 设计要求1.2 总体设计方案 二、终端结点的设计及实现2.1单片机最小系统2.2 LED灯的控制与工作状态的显示2.2.1 硬件设计2.2.2 软件设计 2.3 温度的测量与显示2.4 火灾的监测与报警2.5 串口的显示与控制 三、网络传输与控制3.1 …

three.js 第十一节 - uv坐标

// ts-nocheck // 引入three.js import * as THREE from three // 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js // 导入tween import * as T…

计算机网络(概述)

该笔记为湖科大计算机网络相关笔记、教材参考计算机网络第六版 湖科大计算机网络 计算机网络概述 因特网概述 Internet和internet的区别 internet&#xff1a;只要是计算机与计算机连接&#xff0c;形成了网络&#xff0c;就可以叫internet Internet&#xff1a;泛指全世界的…

现在这个行情,又又又要开始准备面试了~~

亲爱的程序员朋友们: 这些资料曾经帮助过许多有志之士顺利拿下抖音、快手、阿里等大厂的Offer&#xff0c;现在也希望它们能为你的面试旅程助力&#xff01; 关注【程序员世杰】回复【1024】惊喜等你来拿&#xff01; 截图 关注【程序员世杰】回复【1024】惊喜等你来拿&#xf…

【数据分享】《中国法律年鉴》1987-2022

而今天要免费分享的数据就是1987-2022年间出版的《中国法律年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 自1987年起&#xff0c;《中国法律年鉴》作为一部全面记录中国法律发展进程的重要文献&#xff0c;见证了中国法治建设的每…

C语言| 数组的折半查找

数组的折半查找 折半查找&#xff1a;在已经排好序的一组数据中快速查找数据。 先排序&#xff0c;再使用折半查找。 【折半查找的运行过程】 1 存储数组下标 low最小的下标&#xff0c;mid中间的下标&#xff0c; high最大的下标 2 key存放查找的值&#xff0c;每一次对比后…

2024年,业绩大爆发的企业,都做对了一件事

作为新质生产力之一的AI技术&#xff0c;已经完成了从实验室到场景应用的“惊险一跃”&#xff0c;这背后离不开云计算、大数据技术的日趋成熟。与此同时&#xff0c;大模型、柔性计算等创新的云基础设施解决方案&#xff0c;为企业降本增效、快速高质量地发展&#xff0c;提供…

电影数据集关联分析及FP-Growth实现

&#xff08;1&#xff09;数据预处理 我们先对数据集进行观察&#xff0c;其属性为’movieId’ ‘title’ ‘genres’&#xff0c;其中’movieId’为电影的序号&#xff0c;但并不完整&#xff0c;‘title’为电影名称及年份&#xff0c;‘genres’为电影的分类标签。…

【从0实现React18】 (一) 项目初始化

Multi-repo 和 Mono-repo 由于需要同时管理多个包&#xff0c;如React、React-dom等&#xff0c;所以选择**Mono-repo** 选择使用pnpm-workspace搭建Mono-repo环境的原因 依赖安装快更规范 Pnpm初始化 npm install -g pnpm pnpm init配置pnpm-workspace.yml文件 pnpm-work…

【C++提高编程-11】----C++ STL常用集合算法

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

vscode插件path-intellisense失效原因

很可能是因为设置中的自动补全部分除了问题。 问题 作者自身是因为使用了copilot之后&#xff0c;感觉vscod自带的自动补全(设置里面叫"建议"&#xff0c;或者inttelisense)就没必要了&#xff0c;然后一通改设置把建议关掉之后发现插件path-intellisense也不能用了…

CATIA_DELMIA_V5R2019安装包下载及安装教程破解

以下为V5-6R2019安装说明 1.将两卷安装文件解压到同一目录内&#xff0c;互相覆盖即可 &#xff08;按用户需要下载 CATIA 或者DELMIA&#xff09; 以上为 CATIA 的安装包 以上为 DELMIA 的安装包 两者合并到一起&#xff0c;同一目录 2.解压后运行setup.exe 如遇到报错&…

[信号与系统]关于LTI系统的转换方程、拉普拉斯变换和z变换

前言 本文还是作为前置知识。 LTI系统的传递函数 LTI系统的传递函数 H ( z ) H(z) H(z) 是输出信号的z变换 Y ( z ) Y(z) Y(z) 与输入信号的z变换 X ( z ) X(z) X(z) 的比值&#xff1a; H ( z ) Y ( z ) X ( z ) H(z) \frac{Y(z)}{X(z)} H(z)X(z)Y(z)​ 多项式比值表…

【实战分享】雷池社区版助力构建高可用、安全的Web应用架构

引言 在日益复杂的网络环境中&#xff0c;构建坚不可摧的安全防线成为每一位网站守护者的重要使命。本文将深入剖析一套集CDN加速、高效Nginx代理与雷池WAF深度防护于一体的现代网站安全架构设计&#xff0c;特别强调雷池WAF在此架构中的核心作用及其对整体安全性的提升策略。…

作为一名程序员,怎么才能写出简洁实用还漂亮的代码楼呢?这25个超惊艳的Python代码写法,你一定要学会!

前言 Python可以用于复杂的数据分析和Web开发项目&#xff0c;还能以极少的代码行数完成令人惊叹的任务。本文将分享25个简短的Python代码示例&#xff0c;用来展示Python编程语言的魅力和效率。 1.列表推导式 Python的列表推导式提供了一种优雅的方法来创建列表。 # 将一个…