[ c++ ]vector的模拟实现及简单测试参考

vector 的文档介绍
1. vector 是表示可变大小数组的序列容器。
2. 就像数组一样, vector 也采用的连续存储空间来存储元素。也就是意味着可以采用下标对 vector 的元素
进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自
动处理。
3. 本质讲, vector 使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小
为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是
一个相对代价高的任务,因为每当一个新的元素加入到容器的时候, vector 并不会每次都重新分配大
小。
4. vector 分配空间策略: vector 会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存
储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是
对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
5. 因此, vector 占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增
长。
6. 与其它动态序列容器相比( deque, list and forward_list ), vector 在访问元素的时候更加高效,在末
尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起 list forward_list
统一的迭代器和引用更好。
使用 STL 的三个境界:能用,明理,能扩展 ,那么下面学习 vector ,我们也是按照这个方法去学习
简单了解vector过后,这个博客我们主要经行string的常见函数的常见接口的模拟实现,这可以有效帮助大家理解vector。
#pragma once
#include<iostream>
#include<assert.h>
using std::cout;
using std::endl;
namespace king 
{
	template<class T>
	class vector
	{
	public:
		// Vector的迭代器是一个原生指针
		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;
		}

		vector() {

		}
		vector(int n, const T& value = T()) {
			_start = new T[n];
			_endOfStorage = _start + n;
			_finish = _start;
			while (_finish != _endOfStorage) {
				*_finish = value;
				_finish++;
			}
		}

		template<class InputIterator>
		vector(InputIterator first, InputIterator last) 
		{
			
		}

		vector(const vector<T>& v) 
		{
			reserve(v.capacity());
			for (auto& e : v) {   //引用减少拷贝
				push_back(e);
			}
		}

		vector<T>& operator= (vector<T> v) 
		{
			_finish = _start;
			reserve(v.capacity());
			for (auto& e : v) {   //引用减少拷贝
				push_back(e);
			}
			return *this;
		}
		~vector() {
			delete[] _start;
			_start = _finish = _endOfStorage=nullptr;
		}
		// capacity

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

		size_t capacity() const
		{
			return _endOfStorage - _start;
		}
        void reserve(size_t newcapacity) {
			if (_start+newcapacity > _endOfStorage) {
				size_t oldsize = _finish - _start;
				iterator tmp = new T[newcapacity];
				memcpy(tmp, _start, sizeof(T) * oldsize);
				delete[] _start;
				_start = tmp;
				_finish = _start + oldsize;
				_endOfStorage = _start + newcapacity;
			}
			return;
		}

		void resize(size_t n, const T& value = T()) 
		{
			if (n > size()) {
				int count = n-size();
				while (count) {
					push_back(value);
					count--;
				}
			}
			else {
				_finish = _start + n;
			}
		}
		///access///

		T& operator[](size_t pos) {
			return  *(_start + pos);
		}

		const T& operator[](size_t pos)const
		{
			return  *(_start + pos);
		}
		///modify/

		void push_back(T val) {
			if (_finish == _endOfStorage) {
				size_t newcapacity = capacity() == 0 ? 4 : 2 * capacity();
				reserve(newcapacity);
			}
			*_finish = val;
			_finish++;
			return;
		}

		void pop_back() {
			_finish--;
		}

		void swap(vector<T>& v) {
			std::swap(v._start,_start);
			std::swap(v._finish,_finish);
			std::swap(v._endOfStorage,_endOfStorage);
		}

		iterator insert(iterator pos, const T& x) {
			assert(_start <= pos && pos <= _finish);
			iterator cur = _finish;
			while (cur > pos-1) {
				*cur = *(cur - 1);
				cur--;
			}
			_finish++;
			*pos = x;
			return pos;
		}

		iterator erase(iterator pos) {
			assert(_start <= pos && pos <= _finish);
			iterator cur = pos;
			while (cur < _finish-1) {
				*cur = *(cur + 1);
				cur++;
			}
			_finish--;
			return pos;
		}
		
	private:
		iterator _start=nullptr;
		iterator _finish=nullptr;
		iterator _endOfStorage=nullptr;
	};

	void test1() {
		vector<int> t1;
		t1.push_back(4);
		t1.push_back(4);
		t1.push_back(4);
		for (auto e : t1) {
			cout << e << ' ';
		}
		cout << endl;
	}
	void test2() {
		vector<int> t2(10, 1);

		for (auto e : t2) {
			cout << e << ' ';
		}
		cout << endl;
	}
	void test3() {
		vector<int> t3(5,1);
		vector<int> t4(t3);
		vector<int> t5;
		t5 = t3;
		cout << "t3:";
		for (auto e : t3) {
			cout << e << ' ';
		}
		cout << endl;
		cout << "t4:";
		for (auto e : t4) {
			cout << e << ' ';
		}
		cout << endl;
		cout << "t5:";
		for (auto e : t5) {
			cout << e << ' ';
		}
		cout << endl;
	}
	void test4() {
		vector<int> t3(5, 1);
		vector<int> t4(5, 2);

		cout << "t3:";
		for (auto e : t3) {
			cout << e << ' ';
		}
		cout << endl;
		cout << "t4:";
		for (auto e : t4) {
			cout << e << ' ';
		}
		cout << endl;

		t3.pop_back();
		t4.pop_back();

		cout << "t3:";
		for (auto e : t3) {
			cout << e << ' ';
		}
		cout << endl;

		cout << "t4:";
		for (auto e : t4) {
			cout << e << ' ';
		}
		cout << endl;

		t3.swap(t4);
		
		cout << "t3:";
		for (auto e : t3) {
			cout << e << ' ';
		}
		cout << endl;

		cout << "t4:";
		for (auto e : t4) {
			cout << e << ' ';
		}
		cout << endl;
		
		
	}
	void test5() {
		vector<int> t1(10,9);
		for (auto e : t1) {
			cout << e << ' ';
		}
		cout << endl;
		t1.resize(5);
		for (auto e : t1) {
			cout << e << ' ';
		}
		cout << endl;
		t1.resize(10, 1);
		for (auto e : t1) {
			cout << e << ' ';
		}
		cout << endl;
	}
	void test6() {
		vector<int> t6;
		for (int i = 0; i < 10; i++) {
			t6.push_back(i);
		}
		for (auto e : t6) {
			cout << e << ' ';
		}
		cout << endl;
		t6.erase(t6.begin());
		for (auto e : t6) {
			cout << e << ' ';
		}
		cout << endl;
		t6.erase(t6.begin());
		for (auto e : t6) {
			cout << e << ' ';
		}
		cout << endl;
		t6.erase(t6.end());
		for (auto e : t6) {
			cout << e << ' ';
		}
		cout << endl;

	}
	void test7() {
		vector<int> t6;
		for (int i = 0; i < 10; i++) {
			t6.push_back(i);
		}
		for (auto e : t6) {
			cout << e << ' ';
		}
		cout << endl;
		t6.insert(t6.begin(), 0);
		for (auto e : t6) {
			cout << e << ' ';
		}
		cout << endl;
	}
}

                                                    

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

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

相关文章

Square Pair

传送门 题意 思路 实际上我们要的 AiAj 肯定是 (ab)^2 所以我们只需要关注于 ai 这个数经过质因数分解 除掉平方数的结果 也就是Ai​ 除去完全平方数因子 每次我们对ai讨论只需要加上 cnt[a[i]] 即可 此外 0 需要特判 code

mysql 排序底层原理解析

前言 本章详细讲下排序&#xff0c;排序在我们业务开发非常常见&#xff0c;有对时间进行排序&#xff0c;又对城市进行排序的。不合适的排序&#xff0c;将对系统是灾难性的&#xff0c;这个不是危言耸听。可能有些人会想&#xff0c;对于排序mysql 是怎么实现的&#xff0c;…

WWW2024 | PromptMM:Prompt-Tuning增强的知识蒸馏助力多模态推荐系统

论文&#xff1a;https://arxiv.org/html/2402.17188v1 代码&#xff1a;https://github.com/HKUDS/PromptMM 研究动机 多模态推荐系统极大的便利了人们的生活,比如亚马逊和Netflix都是基于多模态内容进行推荐的。对于研究,人们也遵循工业界的趋势,进行modality-aware的用户…

生成器建造者模式(Builder)——创建型模式

生成器/建造者模式——创建型模式 什么是生成器模式&#xff1f; 生成器模式是一种创建型设计模式&#xff0c; 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。 提炼两个关键点&#xff1a;Ⅰ.分步骤创建复杂对象。Ⅱ.相同创建代码…

北斗卫星在桥隧坡安全监测领域的应用及前景展望

北斗卫星在桥隧坡安全监测领域的应用及前景展望 北斗卫星系统是中国独立研发的卫星导航定位系统&#xff0c;具有全球覆盖、高精度定位和海量数据传输等优势。随着卫星导航技术的快速发展&#xff0c;北斗卫星在桥隧坡安全监测领域正发挥着重要的作用&#xff0c;并为相关领域…

python 目录和文件基本操作

目录操作 获取当前目录&#xff1a; import os dir_path os.getcwd() print("当前目录&#xff1a;", dir_path) 当前目录&#xff1a; D:\work\pycharm\object 创建目录&#xff1a; import osdir_path os.getcwd() print("当前目录&#xff1a;", d…

【算法刷题 | 栈】3.16(有效的括号、删除字符串中的所有相邻重复项、逆波兰表达式求值)

文章目录 1.有效的括号1.1题目1.2解法&#xff1a;栈 2.删除字符串中的所有相邻重复项2.1题目2.2解法&#xff1a;栈 3.逆波兰表达式求值3.1题目3.2解法&#xff1a;栈 1.有效的括号 1.1题目 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff…

Midjourney绘图欣赏系列(十二)

Midjourney介绍 Midjourney 是生成式人工智能的一个很好的例子&#xff0c;它根据文本提示创建图像。它与 Dall-E 和 Stable Diffusion 一起成为最流行的 AI 艺术创作工具之一。与竞争对手不同&#xff0c;Midjourney 是自筹资金且闭源的&#xff0c;因此确切了解其幕后内容尚不…

element ui 中文离线文档(百度云盘下载)

一般内网开发上不了网&#xff0c;用离线版本比较方便&#xff0c;下载地址&#xff1a; https://download.csdn.net/download/li836779537/88355878?spm1001.2014.3001.5503 下载后里面有个 index.hrml 双击打开就可以用 效果如下&#xff1a;

ADC架构III:Σ-Δ型ADC基础

简介 Σ-Δ型ADC是现代语音频带、音频和高分辨率精密工业测量应用所青睐的转换器。高度数 字架构非常适合现代细线CMOS工艺&#xff0c;因而允许轻松添加数字功能&#xff0c;而又不会显著增加成 本。随着此转换器架构的广泛使用&#xff0c;了解其基本原理显得非常重要。 历…

河南大学大数据平台技术实验报告二

大数据平台技术课程实验报告 实验二&#xff1a;HDFS操作实践 姓名&#xff1a;杨馥瑞 学号&#xff1a;2212080042 专业&#xff1a;数据科学与大数据技术 年级&#xff1a;2022级 主讲教师&#xff1a;林英豪 实验时间&#xff1a;2024年3月15日3点 至 2024年3月15日4点40 …

C#,入门教程(27)——应用程序(Application)的基础知识

上一篇: C#,入门教程(26)——数据的基本概念与使用方法https://blog.csdn.net/beijinghorn/article/details/124952589 一、什么是应用程序 Application? 应用程序是编程的结果。一般把代码经过编译(等)过程,最终形成的可执行 或 可再用 的文件称为应用程序。可执行文…

数据结构之顺序表(包学包会版)

目录 1.线性表 2.顺序表 2.1概念及结构 2.2接口实现 3.总结 halo&#xff0c;又和大家见面了&#xff0c;今天要给大家分享的是顺序表的知识&#xff0c;跟着我的脚步&#xff0c;包学包会哦~ 规矩不乱&#xff0c;先赞后看&#xff01; ps&#xff1a;&#xff08;孙权…

Android的三种动画详解(帧动画,View动画,属性动画)

Android的三种动画详解&#xff08;帧动画、View动画、属性动画&#xff09;_android动画效果大全-CSDN博客 1、帧动画 缺点是&#xff1a;占用内存较高&#xff0c;播放的是一帧一帧的图片&#xff0c;很少使用。 顺序播放预先定义的图片&#xff0c;类似于播放视频。 步骤…

MySQL语法分类 DDL

DDL(操作数据库、表) 数据库操作(CRUD) C(Create):创建 //指定字符集创建 create database db_1 character set utf8;//避免重复创建数据库报错可以用一下命令 create database if not exists db_1 character set utf8;R(Retrieve):查询 //查询所有数据库的名称 show datab…

基于ElasticSearch存储海量AIS数据:时空立方体索引篇

文章目录 引言I 时间维切分II 空间范围切分引言 索引结构制约着查询请求的类型和处理方式,索引整体架构制约着查询请求的处理效率。随着时间推移,AIS数据在空间分布上具备局部聚集性,如 果简单地将所有AIS数据插入一个索引结构,随着数据量增长,索引的更新效率、查询效率及…

8508A福禄克(FLUKE)数字多用表

181/2461/8938产品概述&#xff1a; Fluke 8508A 万用表在广泛的测量范围内具有卓越的准确性和稳定性&#xff0c;旨在用作校准实验室的多功能精密测量工具&#xff0c;这些实验室必须满足日益严格的测量不确定性分析要求以及提高生产率的需要。 作为其复杂职责的一部分&…

前端项目,个人笔记(一)【Vue-cli - 定制化主题 + 路由设计】

目录 1、项目准备 1.1、项目初始化 1.2、elementPlus按需引入 注&#xff1a;使用cnpm安装elementplus及两个插件&#xff0c;会报错&#xff1a;vueelement-plus报错TypeError: Cannot read properties of null (reading isCE ) &#xff0c;修改&#xff1a; 测试&#…

SSO 单点登录

什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在网络应用间传输声明。它以一种紧凑且自包含的方式安全地在用户和服务之间传递信息&#xff0c;通常用于身份验证和信息交换 为什么要使用JWT 1.传统Se…

解密学习机制:线性回归与梯度下降之旅

摘要 在理解机器学习机制的过程中&#xff0c;我们探讨了在合成数据集上训练简单线性回归模型的过程。整个过程要解决的问题是算法如何通过迭代优化来学习输入和输出变量之间的基本关系。 我们的方法包括生成一个合成线性数据集&#xff0c;实施梯度下降进行参数估计&#xf…