首页 > 其他分享 >vector的模拟实现

vector的模拟实现

时间:2025-01-12 17:58:13浏览次数:3  
标签:end iterator 实现 start vector const 模拟 size

文章目录

vector的模拟实现

  • begin()
  • end()
  • size()
  • capacity()
  • reserve()
  • push_back()
  • pop_back()
  • empty()
  • operator[]
  • insert()

vector.h

#pragma once

#include<iostream>
#include<list>
#include<assert.h>
#include<string>

using namespace std;

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

		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}

		const_iterator begin() const
		{
			return _start;
		}

		const_iterator end() const
		{
			return _finish;
		}

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

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

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

			*_finish = x;
			++_finish;
    	}

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

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

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

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

		iterator insert(iterator pos, const T& x)
		{
			if (_finish == _end_of_storage)
			{
				// 扩容后_start可能会变
				size_t len = pos - _start;
				reserve(capacity() == 0 ? 4 : 2 * capacity());
				pos = _start + len;
				// 所以更新一下pos,不让pos指向原来的空间
			}

			iterator end = _finish - 1;
			while (end >= pos)
			{
				*(end + 1) = *end;
				--end;
			}
			*pos = x;

			++_finish;

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

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

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

	/*void vector_print(const vector<int>& v)
	{
		vector<int>::const_iterator it = v.begin();

		while (it != v.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;

		for (auto x : v)
		{
			cout << x << " ";
		}
		cout << endl;
	}*/

	template<class T>
	void vector_print(const vector<T>& v)
	{
		// 规定没有实例化的类模版里取东西,编译器是无法区分const_iterator是
		// 静态成员变量还是类型,加了typename 就表明是类型
		// typename vector<T>::const_iterator it = v.begin();
		auto it = v.begin();

		while (it != v.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;

		for (auto x : v)
		{
			cout << x << " ";
		}
		cout << endl;

	}

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

		for (size_t i = 0; i < v.size(); i++)
			cout << v[i] << " ";
		cout << endl;

		vector<int>::iterator it = v.begin();
		for (size_t i = 0; i < v.size(); i++)
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;

		for (auto x : v)
			cout << x << " ";
		cout << endl;
 
		vector_print(v);

		vector<double> vv;
		vv.push_back(1.1);
		vv.push_back(2.2);
		vv.push_back(3.3);
		vv.push_back(4.4);
		vv.push_back(5.5);

		vector_print(vv);

	}

	void test_vector2()
	{
		vector<int> v;
		v.push_back(1);
		v.push_back(2);
		v.push_back(3);
		v.push_back(4);
		v.push_back(5);
        
		vector_print(v);

		v.insert(v.begin() + 2, 30);
		vector_print(v);

		int x;
		cin >> x;
		auto pos = find(v.begin(), v.end(), x);
		if (pos != v.end())
		{
			pos = v.insert(pos, 30);
			//(*pos) *= 10;
			(*(pos+1)) *= 10;
		}

		vector_print(v);
	}
}

test.cpp


#include"vector.h"

int main()
{
	wbc::test_vector2();

	return 0;
}

模版不能分离到两个文件 .h和.cpp,会出现链接错误
reserve是不缩容的

  • vector<vector< int >> 调用的是两个类的模版

在这里插入图片描述
在这里插入图片描述

  • vector的底层
protected:
iterator start;
// 数据开始的位置
iterator finish; // 指针 + size()
// 数据结束的下一个位置
iterator end_of_storage;// 指针 + capacity()
// 空间结束的下一个位置

insert_aux(end(),x);
// end() 数据结束的下一个位置
// 在最后一个位置插入x,相当于尾插
  • reserve是怎么给_start,_finish和_end_of_storage的?
// 错误写法
reserve(n > capacity)
{
  _start = tmp;
  _finish = tmp + size();
  // size() 为 _finish - _start
  // 之前的_finish减去更新后的_start
  // 这样肯定是错误的
  _end_of_storage = _start + n;
}

size_t size()
{
   return _finish - _start;
}
// 正确写法
reserve(n > capacity)
{
   _finish = tmp + size();// size()为0
   _start = tmp;
   _end_of_storage = _start + n;
}
  • vector< T >:: const_iterator it = v.begin(),vector< T >未实例化会分不清是类型还是静态成员变量 ?

vector< int > :: const_iterator it = v.begin()
实例化后的vector< int > 可以取到类型
::域作用限定符后面会跟类型或静态成员变量

template<class T>
	void vector_print(const vector<T>& v)
	{
		// 规定没有实例化的类模版里取东西,编译器是无法区分const_iterator是
		// 静态成员变量还是类型,加了typename 就表明是类型
		// typename vector<T>::const_iterator it = v.begin();
		auto it = v.begin();

标签:end,iterator,实现,start,vector,const,模拟,size
From: https://blog.csdn.net/2301_79722622/article/details/145093058

相关文章

  • 基于Informer网络实现电力负荷时序预测——cross validation交叉验证与Hyperopt超参数
    前言系列专栏:【深度学习:算法项目实战】✨︎涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记忆......
  • 使用 smtp 结合 gpt 接口实现的AIGC邮件发送脚本
    一、引言在这个数字化信息爆炸的时代,自动化任务在提高效率和实现个性化服务方面发挥着至关重要的作用。本文将为你详细介绍一个利用GPT接口结合Python实现的邮件发送脚本,该脚本不仅能自动发送邮件,还能通过调用GPT接口生成独特的邮件内容,为你的信息传递带来更多创意和乐......
  • 模拟退火算法在优化问题中的应用
     摘要 本文深入探讨模拟退火算法在优化问题中的应用。首先介绍模拟退火算法的基本原理,包括其物理背景和数学模型。详细阐述算法在解决各类优化问题时的具体步骤,从问题定义、参数初始化到邻域搜索、解的接受与温度更新等环节。通过旅行商问题(TSP)和背包问题等经典案例,展示算......
  • 如何提升原力值-小白专享 快速实现赚钱小目标
    CSDN原力值提升秘籍:全面攻略与实战指南在CSDN这个充满技术活力的社区,原力值是衡量用户活跃度和影响力的重要指标。高原力值不仅代表着你在社区中的威望,还能为你带来更多的机会和资源。那么,如何才能有效提升原力值呢?今天,就为大家详细揭秘。一、内容创作:夯实基础,打造优质输......
  • Kafka 是一个分布式流式平台,主要用于处理大规模、高吞吐量的消息传递、日志收集和实时
    Kafka集群是什么?Kafka是一个分布式流式平台,主要用于处理大规模、高吞吐量的消息传递、日志收集和实时数据流。Kafka集群是由多个Kafka服务器(称为Broker)组成的,它们共同工作以实现消息的高可用性、可靠性、可扩展性和容错性。Kafka集群的目的是确保消息的持久化和高效传输,同......
  • 淘宝商品搜索神器:Python代码实现item_search API调用
    在电商蓬勃发展的今天,淘宝作为国内领先的购物平台,拥有海量商品信息。对于商家、消费者以及市场分析师来说,能够快速、准确地获取淘宝商品数据至关重要。淘宝开放平台提供了丰富的API接口,其中item_search接口便是按关键字搜索商品的利器。本文将详细介绍如何使用Python代码调用淘宝i......
  • 1.12 CW 模拟赛 T1. 括号序列
    思路根据赛时的检验,典型的动点问题的\(\rm{trick}\)并不能在这里使用,也就是说,分类讨论前缀+\(i\)+后缀前缀+\(i\)后缀+\(i\)是不可行的考虑括号串问题的常见做法,先将其赋值成\(1,-1\)之后进行处理你发现这种做法有枚举字段和的瓶颈,所以也不可行......
  • SQL 实现复杂地理围栏 – 多边形区域判断与距离筛选
    在位置服务、物流配送、LBS(基于位置的服务)等场景中,地理围栏(Geofence)是一个重要功能。通过SQL查询,我们可以借助空间索引和地理函数,精准判断目标是否在多边形区域内,或计算两点之间的距离,以实现地理围栏和位置筛选。一、地理围栏的应用场景快递员定位与调度:筛选在特定服务......
  • VS Code+Gitee+Picgo实现图床
    在VSCode中结合Gitee图床和PicGo插件,解决Markdown文档插入图片的问题。步骤一、在VSCode中安装Picgo插件步骤二、在系统中安装Picgo软件进入PicGo官网:https://molunerfinn.com/PicGo/。下载最新版本.exe文件。安装完成后,打开PicGo,点击插件设置,搜索gitee,安装gitee-uploader......
  • asp毕业设计下载(全套源码+配套论文)——基于asp+access的实验室设备管理系统设计与实现
    基于asp+access的实验室设备管理系统设计与实现(毕业论文+程序源码)大家好,今天给大家介绍基于asp+access的实验室设备管理系统设计与实现,更多精选毕业设计项目实例见文末哦。文章目录:基于asp+access的实验室设备管理系统设计与实现(毕业论文+程序源码)1、项目简介2、资源......