vector的模拟实现 总结
vector的模拟实现 总结
- vector.h
- Test.cpp
vector.h
1、迭代器的实现
#pragma oncenamespace JPC
{template<class T>class vector{public://对于存储空间是连续的结构而言,可以用原身指针来 模拟实现 迭代器。typedef T* iterator;typedef const T* const_iterator;//普通迭代器iterator begin(){return _start;}iterator end(){return _finish;}//const 迭代器const iterator begin()const{return _start;}const iterator end()const {return _finish;}
2、求出 capacity \ size,以及实现下标遍历及修改:[]
//求出 capacity \ size,以及实现下标遍历及修改:[]//求出 capacitysize_t capacity()const{return _end_of_storage - _start;}//求出 sizesize_t size()const{return _finish - _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];}
3、取得首、尾数据
//取得首数据T& front(){assert(size()>0);return *_start;}//取得尾数据T& back(){assert(size()>0);return *(_finish-1);}
4、预先开辟空间:reserve
//预先开辟空间void reserve(size_t n){//预先保留 size() 的大小,因为一旦 delete过后,size()就变成0了size_t sz = size(); if (n>capacity()){//先开辟新空间T* tmp = new T[n];//如果旧空间数据存在,再将旧空间的数据拷贝到新空间,并且销毁旧空间if (_start){//memcpy(tmp,_start,sizeof(T)*size()); //浅拷贝//由 浅拷贝 改成 深拷贝for (size_t i=0;i<size();++i){tmp[i] = _start[i];}cout << endl;delete[] _start;}//最后,确定新空间的 _start \ _finish \ _end_of_storage_start = tmp;_finish = _start + sz;_end_of_storage = _start + n;}}
5、resize
//对于resize而言,模拟实现存在以下三种情况://(1)n>capacity(), 需要扩容 + 初始化//(2)n>size(),只需要 初始化//(3)n<size(), 只需要 缩容void resize(size_t n,const T& val=T()){//扩容if (n>capacity()){reserve(n);}if (n>size()){//初始化填值while (_finish<_start+n){*_finish = val;++_finish;}}else{//缩容_finish = _start + n;}}
6、构造函数
//构造函数//(1)无参的构造函数vector():_start(nullptr),_finish(nullptr),_end_of_storage(nullptr){}//(2)用n个val去构造 vectorvector(size_t n,const T& val=T()):_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){reserve(n);for (size_t i=0;i<n;++i){push_back(val);}}//(3)(嵌套模板)去构造 vectortemplate <class InputIterator>vector(InputIterator first, InputIterator last):_start(nullptr),_finish(nullptr),_end_of_storage(nullptr){while (first != last){push_back(*first);++first;}}
7、拷贝构造函数 与 赋值运算符重载
//拷贝构造函数(深拷贝)//(1)传统思维: 进行深拷贝,重新开个空间,拷贝数据过去// v1(v);vector(const vector<T>& v){//重新开空间_start = new T[v.size()];//拷贝数据过去//memcpy(_start,v._start,sizeof(T)*v.size()); //浅拷贝//由 浅拷贝 改成 深拷贝for (size_t i = 0; i < v.size(); ++i){_start[i] = v._start[i];}cout << endl;_finish = _start + v.size();_end_of_storage = _start + v.size();}// v1.swap(v);void swap(vector<T>& v){::swap(_start,v._start);::swap(_finish, v._finish);::swap(_end_of_storage, v._end_of_storage);}(2)现代思维:找个打工人tmp,再复用构造函数 v1(v);//vector(const vector<T>& v)// :_start(nullptr)// , _finish(nullptr)// , _end_of_storage(nullptr)//{// vector<T> tmp(v.begin(),v.end());// swap(tmp);//}//赋值运算符重载// v1=v; (现代思维)vector<T>& operator=(vector<T> v)//返回值vector<T>& 是为了实现 连= ;参数用传值拷贝,便于出了函数的作用域就销毁了{this->swap(v);return *this;}
8、析构函数
//析构函数~vector(){delete[] _start;_start = _finish = _end_of_storage = nullptr;}
9、尾插、尾删; 插入、删除
//尾插void push_back(const T& x){先检测 是否需要扩容//if (_finish==_end_of_storage)//{// reserve(capacity()==0 ? 4:capacity()*2);//}再插入数据//*_finish = x;//++_finish;insert(end(),x);}//尾删void pop_back(){//删除,防止越界了assert(_finish>_start);--_finish;}//插入iterator insert(iterator pos,const T& x){assert(pos>=_start && pos<=_finish);//先检测是否需要扩容if (_finish==_end_of_storage){//在扩容之前需要记录好pos的位置size_t len = pos - _start;reserve(capacity()==0 ? 4:capacity()*2);//扩容之后重新确定pos的位置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 begin = pos;while (begin<_finish-1){*begin = *(begin+1);++begin;}--_finish;return pos;}private:iterator _start; // _start为 vector存储的首个数据的地址(指针)iterator _finish; // _finish为 存储的末尾数据的下一个数据的地址iterator _end_of_storage; //_end_of_storage为 vector内开辟的最后一个空间的下一个空间的地址。};
一、测试 迭代器遍历、下标遍历、尾插、尾删
//测试 迭代器遍历、下标遍历、尾插、尾删
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){++v[i];}//迭代器遍历vector<int>::iterator it = v.begin();while (it != v.end()){--(*it);cout<< *it <<" ";++it;}cout << endl;v.pop_back();v.pop_back();for (size_t i=0;i<v.size();++i){cout<< v[i] <<" ";}cout << endl;
二、测试 const_iterator
//测试 const_iteratorvoid Func(const vector<int>& v){vector<int>::const_iterator it = v.begin();while (it != v.end()){//++(*it); //无法改变 *it 的值cout<< *it <<" ";++it;}cout << endl;}void test_vector2(){const vector<int> v(8,8);//const修饰的对象,只能在定义的时候初始化(赋值),后面无法再改变。Func(v);}
三、用下标[]遍历,测试 insert 和 erase
//用下标[]遍历,测试 insert 和 erasevoid test_vector3(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);for (size_t i = 0; i < v.size(); ++i){cout << v[i] << " ";}cout << endl;v.insert(v.end(),5);for (size_t i = 0; i < v.size(); ++i){cout << v[i] << " ";}cout << endl;v.erase(v.end()-1);v.erase(v.begin());for (size_t i = 0; i < v.size(); ++i){cout << v[i] << " ";}cout << endl;}
四、测试 insert时,迭代器失效的状况
//测试 insert时,迭代器失效的状况void test_vector4(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);auto it = v.begin();while (it != v.end()){cout<< *it <<" ";++it;}cout << endl;auto p = find(v.begin(),v.end(),3); //支持了迭代器,就支持了stl里面的findif (p != v.end()){v.insert(p,30); //当需要在pos位置插入数据时,遇到了vector需要扩容的情况;注意在扩容之后,pos已经失效了(因为pos指向的是原来数组中的某个位置,现在旧数组已经销毁了)。}for (auto e:v){cout<< e <<" ";}cout << endl;}
五、补充:insert的迭代器失效
//补充:insert的迭代器失效void test_vector5(){vector<int> v;//v.reserve(10);v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);//要求在所有偶数前面插入该偶数二倍的数auto it = v.begin();while (it != v.end()){if (*it % 2==0){it=v.insert(it,(*it)*2);//迭代器失效的原因:(1)当没有提前reserve时:因为扩容导致的野指针问题。(2)当提前进行reserve时:pos指向的位置已经不是原来的值了(因为数据挪动)++it;++it;}else{++it;}}for (auto e:v){cout << e << " ";}cout << endl;}
六、erase的迭代器失效——原因是:(pos指向的位置已经不再是原来的值了【由于数据挪动】)
void test_vector6(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);//要求删除所有的偶数auto it = v.begin();while (it != v.end()){没有迭代器更新的代码//if (*it % 2==0)//{// v.erase(it);//}//++it;//有迭代器更新的代码if ((*it) % 2==0){it=v.erase(it); //要更新迭代器,也就是pos的位置}else{++it;}}for (auto e:v){cout<< e <<" ";}cout << endl;}//结论: insert/erase pos位置时,不要直接访问pos。一定要更新,直接访问可能会导致各种出乎意料的结果,这就是所谓的迭代器失效。//【要认为pos失效了,不要访问】
七、测试构造函数(嵌套模板类的,参数是迭代器区间)
//测试构造函数(嵌套模板类的,参数是迭代器区间)void test_vector7(){std::string s1("hello,world");vector<int> v(s1.begin(),s1.end());//这儿:从char进行整型提升到int, 最后打印出ascall码值。for (auto e:v){cout<< e <<" ";}cout << endl;}
八、测试拷贝构造函数
//测试拷贝构造函数void test_vector8(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);for (auto e:v){cout<< e <<" ";}cout << endl;//拷贝构造vector<int> v1(v);for (auto e : v){cout << e << " ";}cout << endl;}
九、测试 赋值运算符重载
//测试 赋值运算符重载void test_vector9(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);v.push_back(5);for (auto e:v){cout << e << " ";}cout << endl;vector<int> v1;v1.push_back(0);v1.push_back(0);v1.push_back(0);v1.push_back(0);v1.push_back(0);v1 = v;for (auto e : v1){cout << e << " ";}cout << endl;}
十、测试 resize 的功能
//测试 resize的功能void test_vector10(){vector<int> v1;v1.resize(10,0);for (auto e:v1){cout<< e <<" ";}cout << endl;vector<int> v2;v2.reserve(10);v2.push_back(1);v2.push_back(2);v2.push_back(3);v2.push_back(4);v2.push_back(5);v2.resize(8,8);for (auto e:v2){cout << e << " ";}cout << endl;v2.resize(20,20);for (auto e : v2){cout << e << " ";}cout << endl;v2.resize(3,3);for (auto e : v2){cout << e << " ";}cout << endl;}
十一、打印出 杨辉三角形
//打印出 杨辉三角形
class Solution
{
public:vector<vector<int>> generate(int numRows){vector<vector<int>> vv;vv.resize(numRows);for (size_t i = 0; i < vv.size(); ++i){vv[i].resize(i + 1, 0); //先确定好各 vv[i]数组的容量大小vv[i].front() = vv[i].back() = 1; //先将 vv[i]数组中的第一个和最后一个元素置为1}//计算出剩余位置的数值for (size_t i = 0; i < vv.size(); ++i){for (size_t j = 0; j < vv[i].size(); ++j){if (vv[i][j] == 0){vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];}}}for (size_t i = 0; i < vv.size(); ++i){for (size_t j = 0; j < vv[i].size(); ++j){cout << vv[i][j] << " ";}cout << endl;}return vv;}};void test_vector11(){Solution().generate(5); //前面的 Solution() 是匿名对象}}
Test.cpp
#include <iostream>
#include <assert.h>
using namespace std;#include "vector.h"int main()
{JPC::test_vector11();return 0;
}
相关文章:
vector的模拟实现 总结
vector的模拟实现 总结 vector.hTest.cpp vector.h 1、迭代器的实现 #pragma oncenamespace JPC {template<class T>class vector{public://对于存储空间是连续的结构而言,可以用原身指针来 模拟实现 迭代器。typedef T* iterator;typedef const T* const_i…...
k8s中的有状态,无状态,pv、pvc等
数据库是一个典型的有状态服务,他的部署和无状态服务是不一样的。 PostgresSQL----基于Kubernetes部署PostgresSQL-CSDN博客 一、创建SC、PV和PVC存储对象 二、部署PostgresSQL Volume Kubernetes 中文指南——云原生应用架构实战手册 有状态应用: …...
springboot+jxls复杂excel模板导出
JXLS 是基于 Jakarta POI API 的 Excel 报表生成工具,可以生成精美的 Excel 格式报表。它采用标签的方式,类似 JSP 标签,写一个 Excel 模板,然后生成报表,非常灵活,简单! Java 有一些用于创建 …...
用selenium webdriver获取网站cookie后,实现免登录上网站
以csdn为例,代码分为两部分。 一、csdn_get_cookies.py为半手动登录网站后获取cookies 二、csdn_use_cookies.py为使用获取到的cookies免登录上网站 #获取登录cookiesfrom selenium import webdriver import jsoncsdn_driver webdriver.Chrome() url "htt…...
如何使用Java进行安全测试?
要使用Java进行安全测试,可以按照以下步骤进行: 确定测试目标:首先,明确要测试的应用程序或系统的安全目标和需求。确定要测试的安全方面,如身份验证、授权、输入验证、安全配置等。 了解安全测试知识:熟悉…...
Linux之Socket函数(详细篇)
本篇是基于Linux man手册的一些总结 socket作用: create an endpoint for communication 函数结构 c #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socket(int domain, int type, int protocol); 描述 socket() …...
Dajngo06_Template模板
Dajngo06_Template模板 6.1 Template模板概述 模板引擎是一种可以让开发者把服务端数据填充到html网页中完成渲染效果的技术 静态网页:页面上的数据都是写死的,万年不变 动态网页:页面上的数据是从后端动态获取的(后端获取数据库…...
快速幂 c++
一般大家写都是 int ans 1; for (int i 1; i < a; i )ans * x;时间复杂度 但是这对于我们还不够,我们要 首先我们得知道一个数学知识 那么求 就有以下递归式 a 能被2整除 a 不能被2整除 (这里a/2是整除) 所以每次都调用 不就是么 最后补充一个东西…...
分享一个基于微信小程序的医院口腔助手小程序 牙科诊所预约小程序 源码 lw 调试
💕💕作者:计算机源码社 💕💕个人简介:本人七年开发经验,擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等,大家有这一块的问题可以一起交流! 💕&…...
Si3262 一款低功耗刷卡+触摸+mcu 三合一SOC芯片
Si3262是-款高度集成的低功耗soC芯片,其集成了基于RISC-V 核的低功耗MCU和工作在13.56MHz的非接触式读写器模块。 该芯片ACD模式下刷卡距离可达4-5cm(天线决定),适用于智能门锁,电子锁,柜锁,桑拿…...
[H5动画制作系列] 奔跑的豹子的四种Demo演化
资源: bg.jpg: leopard.png: 背景透明 peopard2.png 背景不透明 参考代码1: leopard.js: (function(window) {ma function() {this.initialize();}ma._SpriteSheet new createjs.SpriteSheet({images: ["leopard.png"], frames: [[0,0,484,207],[486,0,484,207]…...
如何实现让一个函数能返回多个值的效果
在C语言中,一个函数通常只能返回一个值。但是可以通过指针参数或结构体来模拟返回多个值的效果。 使用指针参数:你可以将需要返回的值作为函数的参数,通过指针的形式传入,让函数将结果写入指针所指向的内存位置。 void multiple…...
End-to-end 3D Human Pose Estimation with Transformer
基于Transformer的端到端三维人体姿态估计 摘要 基于Transformer的架构已经成为自然语言处理中的常见选择,并且现在正在计算机视觉任务中实现SOTA性能,例如图像分类,对象检测。然而,卷积方法在3D人体姿态估计的许多方法中仍然保…...
状态管理Pinia
Vue3 状态管理 - Pinia 1. 什么是Pinia Pinia 是 Vue 的专属的最新状态管理库 ,是 Vuex 状态管理工具的替代品 2. 手动添加Pinia到Vue项目 后面在实际开发项目的时候,Pinia可以在项目创建时自动添加,现在我们初次学习,从零开始…...
maven运行报错解决
在IDEA上运行较大项目时,编译量很大,可能会报出 Error:java: java.lang.OutOfMemoryError: Java heap space 的错误,解决方法如下: java.lang.OutOfMemoryError是内存不足导致的,因此需要修改Idea运行项目的内存大小。…...
在线会计软件推荐:高效实用的选择解析
如果您始终在密切关注Zoho,您一定知道,我们的软件在一个接一个的增加,为的是构建出一套可以全面在线协作、提升业务生产力的应用系统,我们始终致力于为各类企业构建完整的业务应用,以便他们在Zoho上运行整个业务系统。…...
vue监听Enter键
目录 keydown.enter 方法1: 使用keydown.enter指令 方法2: 在keydown事件处理函数中检查按下的键 keyup.enter.native keydown.enter与keyup.enter.native区别 1. 触发时机: 2. 事件类型: 3. 事件冒泡: keydown.enter 在Vue中监听En…...
ADS中带通滤波器模型参数含义学习笔记
ADS中带通滤波器模型参数含义 1、 Fcenter 中心频率 2、 BWpass 通带带宽 3、 Apass 衰减量时的通带带宽 这两个是对应的,比如说是80MHz,3dB,那么就是3dB时的带宽为80MHz,如果改为0.1dB,那么带宽就是0.1dB时的带宽为80…...
【Blender】Blender入门学习
目录 0 参考视频教程0.1 Blender理论知识0.2 Blender上手实践0.3 FBX模型导入Unity 1 Blender的窗口介绍1.1 主界面1.2 模型编辑窗口 2 Blender的基本操作2.1 3D视图的平移2.2 3D视图的旋转2.3 3D视图的缩放2.4 修改快捷键2.5 使物体围绕选择的物体旋转2.6 四视图的查看2.7 局部…...
Redis 三种特殊的数据类型 - Geospatial地理位置 - Hyperloglog基数统计的算法 - Bitmaps位图(位存储)
目录 Redis 三种特殊的数据类型: Geospatial:地理位置 Geospatial类型常用的命令: GEOADD:添加地理位置 GEOPOS:获取地理位置 GEODIST:返回两个给定位置之间的距离 GEORADIUS:以给定的经纬…...
Python web 框架web.py「简约美」
web.py is a web framework for Python that is as simple as it is powerful. web.py is in the public domain, you can use it for whatever purpose with absolutely no restrictions. web.py 是一个简单而强大的 Python Web 框架。web.py 属于公共领域,您可以…...
Bootstrap 重新数据查询时页码为当前页问题
记录一下使用前端组件Bootstrap遇到的一个小问题: 问题描述 第一次查询数据为5页,翻页到第5页后,选中条件再次查询数据时,传到后端页码仍旧为5,而此时数据量小于5页,这时候页码没有重置成第一页ÿ…...
scratch舞蹈比赛 2023年5月中国电子学会图形化编程 少儿编程 scratch编程等级考试四级真题和答案解析
目录 scratch舞蹈比赛 一、题目要求 1、准备工作 2、功能实现 二、案例分析...
windows下安装redis扩展库
1.根据PHP版本号,编译器版本号和CPU架构 选择php_redis和php_igbinary文件(如果是选择线程的情况下需要再去配置php5ts.dll) windows.php.net - /downloads/pecl/releases/redis/ windows.php.net - /downloads/pecl/releases/igbinary/ php_igbinary-3.1.2-7.2-…...
大数据平台数据安全具体措施有哪些?有推荐的吗?
大数据平台是企业处理和分析数据的重要工具之一,也是企业数据存储的重要载体,因此保障大数据平台安全至关重要。那你知道大数据平台数据安全具体措施有哪些?有推荐的吗? 大数据平台数据安全具体措施有哪些? 1、数据…...
基于SSM的健康综合咨询问诊平台设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...
每日一题 2596. 检查骑士巡视方案
难度:中等 很简单,从第 0 步开始模拟即可,唯一sb的就是测试用例中如果(0,0)处不为0的话就直接false,而不是去找0在哪 我的代码: class Solution:def checkValidGrid(self, grid: L…...
第二章 进程与线程 三、进程控制
目录 一、定义 二、实现方式(用原语实现) 注意: 1、原语是什么 2、如何实现原语的原子性 3、关中断指令和开中断指令是什么 三、进程控制的相关原语 1、进程的创建 编辑 2、进程的终止 3、进程的阻塞与唤醒(阻塞和唤醒…...
【云原生进阶之PaaS中间件】第二章Zookeeper-3.2架构详解
1 Zookeeper工作原理 1.1 Zookeeper的角色 领导者(leader),负责进行投票的发起和决议,更新系统状态 学习者(learner),包括跟随者(follower)和观察者(obser…...
K8S:kubectl陈述式、声明式资源管理及金丝雀部署
文章目录 一.陈述式资源管理方法1.陈述式资源管理概念2.基本信息查看(1)查看版本信息(2)查看资源对象简写(3)查看集群信息(4)配置kubectl自动补全(5)node节点…...
做网站需要什么认证/只要做好关键词优化
专栏 | 九章算法网址 | http://www.jiuzhang.com问1动态规划是个什么鸟蛋?答:动态规划是一种通过“大而化小”的思路解决问题的算法。区别于一些固定形式的算法,如二分法,宽度优先搜索法,动态规划没有实际的步骤来规定…...
论述政府门户网站建设的基本意义/国外免费舆情网站有哪些软件
作用:不借助<router-link>实现路由跳转,让路由跳转更加灵活 具体编码: $router.push 想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏…...
便宜网站建设成都/在线企业管理培训课程
临界区(criticalSection) 又称阻塞,它能够使一段代码只由一个线程来执行,其它线程被挡在这段代码之外,直到第一个线程执行完代码。临界区的使用主要涉及如下API函数: initializeCriticalSection(), 在临界区…...
做外贸什么网站比较好/网络推广竞价外包
在虚拟机中安装 Ubuntu 步骤 安装前的准备和基本安装设置语言环境安装常用软件 1. 安装前的准备和基本安装 1.1 安装前的准备 访问 http://cn.ubuntu.com/download/ 下载 Ubuntu 16.04 版本在操作系统上安装 VMWare 虚拟机软件 为什么要使用虚拟机? 不需要准备…...
权威网站发布平台/优化关键词软件
这个夏天,如果你还不了解网络安全大赛,你就out了。“现男友”李现在《亲爱的,热爱的》剧中扮演的韩商言是CTF(可译为“夺旗赛”)职业选手,让这个原本在大众眼里比较陌生的职业一下子就火了。同时带火的还有…...
wordpress备案号添加到哪里/免费网页在线客服系统
如果您是创建类的人,则可以在实例化类时简单地存储弱引用:import weakref class A(object): instances = [] def __init__(self): A.instances.append(weakref.ref(self)) a, b, c = A(), A(), A() instances = [ref() for ref in A.instances if ref() is not None] 使用弱引…...