vector类(二)

文章目录

  • vector类的模拟实现
    • 1.默认成员变量和函数
    • 2.迭代器函数
    • 3.空间容量和长度
    • 4.[ ]下标调用
    • 5.插入操作(尾插)
    • 6.调整容量大小
    • 7.判空操作
    • 8.删除操作
    • 9.插入操作
    • 10.size空间大小
    • 11.消除操作

vector类的模拟实现

1.默认成员变量和函数

首先自定义构造vector类的默认成员变量和函数

声明和定义均在头文件(自己创建的vector.h中进行,主函数仅调用函数

#pragma once
#include <iostream>
using namespace std;
#include <vector>

namespace pzh  //自定义的命名空间名称
{
	template<class T>  //类模板
	class vector
	{
	public:
		vector()  //构造函数
			: _start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{}

		~vector()  //析构函数
		{
			delete[] _start;
			_start = _finish = _end_of_storage = nullptr;
		}

	private:
		iterator _start;  //空间开始位置
		iterator _finish;  //空间内字符的最后位置
		iterator _end_of_storage;  //空间的最后位置
	}
}

2.迭代器函数

typedef T* iterator;  //普通迭代器
typedef const T* const_iterator;  //const迭代器

iterator begin()
{
	return _start;
}

iterator end()
{
	return _finish;
}

const_iterator begin() const
{
	return _start;
}

const_iterator end() const
{
	return _finish;
}

迭代器输出容器:

void test_vector()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);

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

输出结果:

在这里插入图片描述

3.空间容量和长度

定义常规函数:

size_t capacity() const  //空间容量
{
	return _end_of_storage - _start;
}

size_t size() const  //空间内容长度
{
	return _finish - _start;
}

4.[ ]下标调用

const T& operator[](size_t pos) const
{
	assert(pos < size());  //需要包含头文件#include <assert.h>
	return _start[pos];
}

5.插入操作(尾插)

void push_back(const T& x)  //插入
{
	if (_finish == _end_of_storage)  //检查容量
	{
		reserve(capacity() == 0 ? 4 : capacity() * 2);  //检查空间,不足时调整容量大小, 扩容2倍
    }
	*_finish = x;
	++_finish;
}

6.调整容量大小

void reserve(size_t n)  //n是扩容后的大小
{
	if (n > capacity())  //原容量比目标容量小,需要扩容
	{
		size_t sz = size();  
		T* tmp = new T[n];
		if (_start)
		{
			memcpy(tmp, _start, sizeof(T) * size());
			delete _start;
		}
		_start = tmp;
		_finish = tmp + sz;
		_end_of_storage = _start + n;
	}
}

功能测试

main.cpp函数:

#define _CRT_SECURE_NO_WARNINGS
#include "vector.h"

int main()
{
	test_vector();  //调用函数,测试功能
	return 0;
}

测试函数:

void test_vector()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	for (size_t i = 0; i < v1.size(); ++i)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
}

测试结果:

在这里插入图片描述

7.判空操作

可以想象成以恶搞指针,指针通常有空指针,也就是所谓的判空操作:

bool empty()
{
	return _start == _finish;  //空返回1,非空返回0
}

测试函数:

void test_vector()
{
	vector<int> v1;
	cout << v1.empty() << endl;
	v1.push_back(1);
	cout << v1.empty() << endl;
}

测试结果:

在这里插入图片描述

8.删除操作

void pop_back()  //删除
{
	assert(!empty());
	--_finish;
}

测试函数:

void test_vector()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);

	v1.pop_back();  //无参,删除最后一个元素
	for (auto e : v1)
	{
		cout << e << " ";
	}
}

输出结果i:

在这里插入图片描述

9.插入操作

void insert(iterator pos, const T& val)  //在pos位置插入val值
{
	assert(pos >= _start);
	assert(pos <= _finish);
	if (_finish == _end_of_storage)  //检查容量
	{
		size_t newCapacity = (0 == capacity()) ? 1 : capacity() * 2;
		reserve(newCapacity);
		pos = _start + size(); // 如果发生了增容,需要重置pos
	}
	iterator end = _finish - 1;
	while (end >= pos)
	{
		*(end + 1) = *end;
		--end;
	}
	*pos = val;
	++_finish;
}

测试函数:

void test_vector()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);

	v1.insert(v1.begin(), 0);  //在最开始位置插入0
	v1.insert(v1.begin() + 3, 100);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

输出结果:
在这里插入图片描述

10.size空间大小

void resize(size_t n,T val = T())
{
	if(n < size())
	{
		//删除数据
		_finish = _start + n;
	}
	else
	{
		if (n > capacity())
		{
			reserve(n);
		}
		while (_finish != _start + n)
		{
			*_finish = val;
			++_finish;
		}
	}
}

测试函数:

void test_vector()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);

	v1.resize(3); 
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;

	v1.resize(6);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}

输出结果:

在这里插入图片描述

11.消除操作

iterator erase(iterator pos)
{
	//挪动数据进行删除
	iterator begin = pos + 1;
	while (begin != _finish) 
	{
		*(begin - 1) = *begin;
		++begin;
	}
	--_finish;
	return pos;
}

测试函数:

	void test_vector()
	{
		vector<int> v1;
		v1.push_back(1);
		v1.push_back(2);
		v1.push_back(3);
		v1.push_back(4);
		v1.push_back(5);

		v1.erase(v1.begin()+2);   //删除第三个位置的元素
		for (auto e : v1)
		{
			cout << e << " ";
		}
		cout << endl;
	}

输出结果:

在这里插入图片描述

综上:

vector.h文件全部内容:

#pragma once
#include <iostream>
using namespace std;
#include <assert.h>

namespace pzh  //自定义的命名空间名称
{
	template<class T>  //类模板
	class vector
	{
	public:
		typedef T* iterator;  //普通迭代器
		typedef const T* const_iterator;  //const迭代器

		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		const_iterator begin() const
		{
			return _start;
		}

		const_iterator end() const
		{
			return _finish;
		}

		vector()  //构造函数
			: _start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{}

		~vector()  //析构函数
		{
			delete[] _start;
			_start = _finish = _end_of_storage = nullptr;
		}

		size_t capacity() const 
		{
			return _end_of_storage - _start;
		}

		size_t size() const 
		{
			return _finish - _start;
		}

		const T& operator[](size_t pos) const
		{
			assert(pos < size());
			return _start[pos];
		}

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

		void reserve(size_t n)  
		{
			if (n > capacity())  
			{
				size_t sz = size();
				T* tmp = new T[n];
				if (_start)
				{
					memcpy(tmp, _start, sizeof(T) * size());
					delete _start;
				}
				_start = tmp;
				_finish = tmp + sz;
				_end_of_storage = _start + n;
			}
		}

		bool empty()
		{
			return _start == _finish;  
		}

		void pop_back()  
		{
			assert(!empty());
			--_finish;
		}

		void insert(iterator pos, const T& val)  
		{
			assert(pos >= _start);
			assert(pos <= _finish);
			if (_finish == _end_of_storage) 
			{
				size_t newCapacity = (0 == capacity()) ? 1 : capacity() * 2;
				reserve(newCapacity);
				pos = _start + size(); 
			}
			iterator end = _finish - 1;
			while (end >= pos)
			{
				*(end + 1) = *end;
				--end;
			}
			*pos = val;
			++_finish;
		}

		void resize(size_t n, T val = T())
		{
			if (n < size())
			{
				//删除数据
				_finish = _start + n;
			}
			else
			{
				if (n > capacity())
				{
					reserve(n);
				}
				while (_finish != _start + n)
				{
					*_finish = val;
					++_finish;
				}
			}
		}

		iterator erase(iterator pos)
		{
			iterator begin = pos + 1;
			while (begin != _finish)
			{
				*(begin - 1) = *begin;
				++begin;
			}
			--_finish;
			return pos;
		}

	private:
		iterator _start;
		iterator _finish;
		iterator _end_of_storage;
	};

	void test_vector()
	{
		//.......
		//测试函数
	}
}

main.cpp函数内容:

#define _CRT_SECURE_NO_WARNINGS
#include "vector.h"


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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uni-app(自定义题色变量)

1.安装sass npm i sass -D 2.安装sass-loader npm i sass-loader10.1.1 -D 3.创建自定义文件 在根目录static目录下&#xff0c;创建scss->_them.scss&#xff0c;目录名称及文件名称自定义即可。 4.定义颜色变量 在_them.scss中&#xff0c;自定义颜色变量&#xff0…

纯分享万岳外卖跑腿系统客户端源码uniapp目录结构示意图

系统买的是商业版&#xff0c;使用非常不错有三端uniapp开源代码&#xff0c;自从上次分享uniapp后有些网友让我分享下各个端的uniapp下的各个目录结构说明 我就截图说以下吧&#xff0c;

鸿蒙OS开发实例:【Web网页】

背景 HarmonyOS平台通过Web控件可支持网页加载展示&#xff0c;Web在中是作为专项参考的。 本篇文章将从Android和iOS平台研发角度出发来实践学习API功能 说明 整个示例是以HarmonyOS开发文档网址作为加载目标页面布局增加了三个按钮“后退”&#xff0c;“前进”&#xff…

Redis、Mysql双写情况下,如何保证数据一致

Redis、Mysql双写情况下&#xff0c;如何保证数据一致 场景谈谈数据一致性三个经典的缓存模式Cache-Aside Pattern读流程写流程 Read-Through/Write-Through&#xff08;读写穿透&#xff09;Write behind &#xff08;异步缓存写入&#xff09; 操作缓存的时候&#xff0c;删除…

Solidity Uniswap V2 Router swapTokensForExactTokens

最初的router合约实现了许多不同的交换方式。我们不会实现所有的方式&#xff0c;但我想向大家展示如何实现倒置交换&#xff1a;用未知量的输入Token交换精确量的输出代币。这是一个有趣的用例&#xff0c;可能并不常用&#xff0c;但仍有可能实现。 GitHub - XuHugo/solidit…

联想 lenovoTab 拯救者平板 Y700 二代_TB320FC原厂ZUI_15.0.677 firmware 线刷包9008固件ROM root方法

联想 lenovoTab 拯救者平板 Y700 二代_TB320FC原厂ZUI_15.0.677 firmware 线刷包9008固件ROM root方法 ro.vendor.config.lgsi.market_name拯救者平板 Y700 ro.vendor.config.lgsi.en.market_nameLegion Tab Y700 #ro.vendor.config.lgsi.short_market_name联想平板 ZUI T # B…

JMM Java内存模型

JMM本身是一个抽象的概念,不是真实存在的,它仅仅是一种规定或者说是规范 1.用来实现线程和主内存直接的抽象关系 2.屏蔽各个硬件平台和操作系统的内存访问差异,使得java程序在各种平台都能达到一致的内存访问效果 JMM的三大特性 可见性 多线程环境下,某个线程修改了变量…

Day55:WEB攻防-XSS跨站CSP策略HttpOnly属性Filter过滤器标签闭合事件触发

目录 XSS跨站-安全防御-CSP XSS跨站-安全防御-HttpOnly XSS跨站-安全防御-XSSFilter(过滤器的意思) 1、无任何过滤 2、实体化 输入框没有 3、全部实体化 利用标签事件 单引号闭合 4、全部实体化 利用标签事件 双引号闭合 5、事件关键字过滤 利用其他标签调用 双引号闭合…

Groovy基础入门

一、Groovy简介 Groovy是运行在JVM中的一种动态语言&#xff0c;可以在Java平台上进行编程&#xff0c;使用方式基本与使用Java代码的方式相同&#xff0c;它的语法与Java语言的语法很相似&#xff0c;与Java相比&#xff0c;Groovy更加灵活、简洁&#xff0c;而且完成同样的功…

Python人工智能:气象数据可视化的新工具

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;在数据处理、科学计算、数学建模、数据挖掘和数据可视化方面具备优异的性能&#xff0c;这些优势使得Python在气象、海洋、地理、气候、水文和生态等地学领域的科研和工程项目中得到广泛应用。可以…

Mybatis别名 动态sql语句 分页查询

给Mybatis的实体类起别名 给Mybatis的xml文件注册mapper映射文件 动态sql语句 1 if 2 choose 3 where 4 foreach 一&#xff09;if 查询指定名称商品信息 语法&#xff1a; SELECT * FROM goods where 11 <if test "gName!null"> and g.g_name like co…

微信小程序被删除的文件一编译又回来了

一开始创建错了位置&#xff0c;就想着删除文件重新创建&#xff0c;但是没想到每次重新编译的时候&#xff0c;之前被删除的js、wsml文件就又回来了&#xff0c;后来发现是我在app.json中的pages里面的代码没有被删除。 因为我最开始创建错了&#xff0c;快捷创建了页面&#…

黑苹果睡眠(电源设置参考),英特尔 NUC9 黑苹果 Sonoma 14.1.1

机型&#xff1a;英特尔 NUC9 i9-9980HK处理器 之前电源配置没设置好&#xff0c;导致经常睡眠被无故唤醒&#xff0c;处理好之后是这样子的设置&#xff0c;我是台式机&#xff0c;其它的不太清楚&#xff0c;可以提供一个参考给大家。 EFI 暂时没时间上传共享&#xff0c;到时…

react-navigation:

我的仓库地址&#xff1a;https://gitee.com/ruanjianbianjing/bj-hybrid react-navigation&#xff1a; 学习文档&#xff1a;https://reactnavigation.org 安装核心包: npm install react-navigation/native 安装react-navigation/native本身依赖的相关包: react-nativ…

计算机网络:物理层 - 信道极限容量

计算机网络&#xff1a;物理层 - 信道极限容量 实际信道中的数字信号奈式准则香农公式练习 实际信道中的数字信号 信号在传输过程中会受到各种因素的影响&#xff0c;如图所示&#xff1a; 这是一个数字信号&#xff0c;当它通过实际的信道后&#xff0c;波形会产生失真&#…

【论文阅读】FlipCAM:高分辨率遥感影像弱监督建筑物提取的特征级翻转增强方法

【论文阅读】FlipCAM&#xff1a;高分辨率遥感影像弱监督建筑物提取的特征级翻转增强方法 文章目录 【论文阅读】FlipCAM&#xff1a;高分辨率遥感影像弱监督建筑物提取的特征级翻转增强方法一、介绍二、方法2.1 准备2.2 一致性的架构2.3 SAM模块2.4 建筑提取模式 三、实验结果…

RISC-V特权架构 - 中断定义

RISC-V特权架构 - 中断定义 1 中断类型1.1 外部中断1.2 计时器中断1.3 软件中断1.4 调试中断 2 中断屏蔽3 中断等待4 中断优先级与仲裁5 中断嵌套6 异常相关寄存器 本文属于《 RISC-V指令集基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 中断类型 RISC-V 架构定义的中…

力扣热门算法题 135. 分发糖果,146. LRU 缓存,148. 排序链表

135. 分发糖果&#xff0c;146. LRU 缓存&#xff0c;148. 排序链表&#xff0c;每题做详细思路梳理&#xff0c;配套Python&Java双语代码&#xff0c; 2024.03.28 可通过leetcode所有测试用例。 目录 135. 分发糖果 解题思路 完整代码 Python Java 146. LRU 缓存 …

图腾柱PFC:HP1010为您的电动两轮车之旅提供绿色,高效,安全的动力

电动两轮车不仅为当今生活提供了便利&#xff0c;更是一种健康和绿色的出行方式。想象一下&#xff0c;在经过一整晚的充分休息&#xff0c;骑上爱车&#xff0c;满血复活的准备开始新的一天。您会愿意带着如何给心爱的两轮车充电的担心开始这一天吗&#xff1f; 随着越来越…

Vue 04 Vue 中的 Ajax、slot 插槽

Vue学习 Vue 0401 Vue中的Ajax服务器准备axios使用跨域问题解决Vue-CLI 配置代理1Vue-CLI 配置代理2案例: 用户搜索vue-resource 02 slot插槽默认插槽具名插槽作用域插槽slot总结 Vue 04 B站 Vue全家桶&#xff08;BV1Zy4y1K7SH&#xff09; 学习笔记 Vue 中的 ajax 01 Vue中的…