当前位置: 首页 > news >正文

福建省建设执业资格管理注册中心网站/关键词搜索工具好站网

福建省建设执业资格管理注册中心网站,关键词搜索工具好站网,广州网站开发定制公司,东莞做网站it s🎬慕斯主页:修仙—别有洞天 ♈️今日夜电波:くちなしの言葉—みゆな 0:37━━━━━━️💟──────── 5:28 🔄 ◀️ ⏸ ▶️ ☰…

                                                      🎬慕斯主页修仙—别有洞天

                                                       ♈️今日夜电波:くちなしの言葉—みゆな

                                                                0:37━━━━━━️💟──────── 5:28
                                                                    🔄   ◀️   ⏸   ▶️    ☰ 

                                      💗关注👍点赞🙌收藏您的每一次鼓励都是对我莫大的支持😍


目录

一、vector实际的底层原理

二、vector的模拟实现

         迭代器相关

         基本操作(迭代器失效问题)

        插入 

        删除 

        push_back()

        pop_back()

         swap()

         基本成员函数

         构造函数

        拷贝构造函数 

        析构函数 

        赋值运算符 

         空间管理

        基本状态 

         扩容操作

        resize() 

         重载[ ](最爱的运算符!!!)

 三、整体代码


一、vector实际的底层原理

        C++中的vector底层实现是一个动态数组,也被称为可变数组。当向vector添加元素时,如果数组已经被填满,vector会自动创建一个更大的数组,将原有数据复制到新数组中,并将新元素添加到新数组中。这种自动扩容的机制使得vector能够封装任意数量的对象,而不必关心底层的数组大小。

        vector的成员变量同前面我们学的string不一样,他是通过使用指针来控制起始位置、最后一个数据位置、最大容量位置。定义如下:

class vector
{
public:typedef T* iterator;typedef const T* const_iterator;
private:iterator _start;  iterator _finish;iterator _endofstorage;
};

        配合图解明白: 

二、vector的模拟实现

         迭代器相关

        // 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;}

         基本操作(迭代器失效问题)

        插入 

        在插入元素期间,可能会引起扩容,让三个指针都指向新的空间,原空间被释放,从而导致原来的迭代器指向的空间错误,对此我们可以返回新的空间的地址解决。

 iterator insert(iterator pos, const T& x)//迭代器失效,返回新的迭代器解决{assert(pos >= _start);assert(pos <= finish);if (_finish == _endOfStorage){size_t len = pos - _start;//避免位置错误,因为在扩容后_start的地址会变化reserve(capacity() == 0 ? 4 : capacity() * 2);pos = start + len;//恢复位置}iterator end = _finish - 1;while (end >= pos)//从后往前挪{*(end + 1) = *end;--end;}*pos = x;++_finish;return pos;}

        删除 

         删除由于受限制,在这里实现的时候只能通过返回指针来控制删除。通常在使用 erase 进行删除时,我们需要额外定义一个迭代器来接受原迭代器,通过选择语句来进行批量删除的判断。有如下例子:(我们要删除迭代器中可以被2整除的数,以此解决迭代器的问题)

 

iterator erase(Iterator pos)//迭代器失效,返回新的迭代器解决{assert(pos >= _start);assert(pos < _finish);iterator it = pos + 1;//定义一个变量用于删除while (it < _finish){*(it - 1) = *it;++it;}--_finish;return pos;}

        push_back()

        复用以上insert的操作,简化代码 。

 void push_back(const T& x){/*if (_finish == _endofstorage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finish = x;++_finish;*/insert(end(), x);}

        pop_back()

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

         swap()

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

         基本成员函数

        主要是复用上面的基本操作以此来简化代码。 

         构造函数

            vector():_start(nullptr),_finish(nullptr),_endOfStorage(nullptr){}

        在构造时,由于我们都要初始化。我们可以直接给成员变量在定义时就给缺省值,剩下的两个分别是根据指定数量、指定初始化值,以及根据迭代器构造。 

            vector(){}vector(int n, const T& value = T()){reserve(n);for (int i = 0; i < n; i++){push_back(value);}}template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}

        拷贝构造函数 

        特别注意,在进行拷贝构造时,不要使用memcpy,在对诸如:string等类型进行拷贝时,执行的是浅拷贝。我们在这复用push_back()来进行拷贝构造。

vector(const vector<T>& v){reserve(v.capacity());for (auto& e : v){push_back(e);}}

        析构函数 

        需要释放在堆上动态开辟的空间,并且将指针置空,防止野指针。

        ~vector(){delete[] _start;_start = _finish = _endofstorage = nullptr;}

        赋值运算符 

        vector<T>& operator= (vector<T> v){swap(v);return *this;}

         空间管理

        基本状态 

        size_t capacity() const{return _endofstorage - _start;}size_t size() const{return _finish - _start;}bool empty()const{return size() == 0;}

         扩容操作

        注意这里不能使用memcpy进行对原有数据的拷贝操作,使用memcpy对于一些存储结构,如string等所做的是浅拷贝的操作。对此,使用会造成很多问题。

        void reserve(size_t n){if (n > capacity()){T* tmp = new T[n];size_t sz = size();if (_start){//memcpy(tmp, _start, sizeof(T) * sz)//这里用memcpy这里会导致string的vector出错,浅拷贝问题for (size_t i = 0; i < sz; i++){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_endOfStorage = _start + n;}}

        resize() 

         如果要扩的空间(n)小于当前数据个数,则截取数据。如果要扩的空间(n)大于当前数据个数则扩容。

        void resize(size_t n, const T& value = T()){if (n < size()){_finish =_start + n;}else{reserve(n);while (_finish < _start + n){*_finish = val;++_finish;}}}

         重载[ ](最爱的运算符!!!)

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

 三、整体代码

#pragma once
#define _CRT_SECURE_NO_WARNINGS 01
#include<iostream>
using namespace std;namespace lt{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;}// construct and destroyvector():_start(nullptr),_finish(nullptr),_endOfStorage(nullptr){}vector(int n, const T& value = T()){reserve(n);for (int i = 0; i < n; i++){push_back(value);}}template<class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}vector(const vector<T>& v){reserve(v.capacity());for (auto& e : v){push_back(e);}}vector<T>& operator= (vector<T> v){swap(v);return *this;}~vector(){delete[] _start;_start = _finish = _endofstorage = nullptr;}// capacitysize_t capacity() const{return _endofstorage - _start;}size_t size() const{return _finish - _start;}bool empty()const{return size() == 0;}void reserve(size_t n){if (n > capacity()){T* tmp = new T[n];size_t sz = size();if (_start){//memcpy(tmp, _start, sizeof(T) * sz)//这里用memcpy这里会导致string的vector出错,浅拷贝问题for (size_t i = 0; i < sz; i++){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + sz;_endOfStorage = _start + n;}}void resize(size_t n, const T& value = T()){if (n < size()){_finish =_start + n;}else{reserve(n);while (_finish < _start + n){*_finish = val;++_finish;}}}///access///T& operator[](size_t pos){assert(pos < size());return _start[pos];}const T& operator[](size_t pos)const{assert(pos < size());return _start[pos];}///modify/void push_back(const T& x){/*if (_finish == _endofstorage){reserve(capacity() == 0 ? 4 : capacity() * 2);}*_finish = x;++_finish;*/insert(end(), x);}void pop_back(){assert(!empty());--_finish;}void swap(vector<T>& v){std::swap(_start, v._start);std::swap(_finish, v._finish);std::swap(_endofstorage, v._endofstorage);}iterator insert(iterator pos, const T& x)//迭代器失效,返回新的迭代器解决{assert(pos >= _start);assert(pos <= finish);if (_finish == _endOfStorage){size_t len = pos - _start;//避免位置错误,因为在扩容后_start的地址会变化reserve(capacity() == 0 ? 4 : capacity() * 2);pos = start + len;//恢复位置}iterator end = _finish - 1;while (end >= pos)//从后往前挪{*(end + 1) = *end;--end;}*pos = x;++_finish;}iterator erase(Iterator pos)//迭代器失效,返回新的迭代器解决{assert(pos >= _start);assert(pos < _finish);iterator it = pos + 1;//定义一个变量用于删除while (it < _finish){*(it - 1) = *it;++it;}--_finish;return pos;}private:iterator _start = nullptr; // 指向数据块的开始iterator _finish = nullptr; // 指向有效数据的尾iterator _endOfStorage = nullptr; // 指向存储容量的尾};}

                       感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o! 

                                       

                                                                         给个三连再走嘛~  

相关文章:

【C++学习手札】模拟实现vector

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;くちなしの言葉—みゆな 0:37━━━━━━️&#x1f49f;──────── 5:28 &#x1f504; ◀️ ⏸ ▶️ ☰…...

Python将图片按照表格形式排列

图片按照表格的形式排列&#xff0c;可以使用图像处理库Pillow来实现 事例代码 from PIL import Image, ImageDraw# 创建一个画布&#xff0c;用来存放排列后的图片 canvas Image.new(RGB, (800, 600), white)# 读取图片 im1 Image.open(image1.jpg) im2 Image.open(image…...

Linux 简要命令记录

1、设置时区&#xff1a; #设为上海&#xff1a; timedatectl set-timezone Asia/Shanghai #搜索特定时区 timedatectl list-timezone2、修改时间&#xff1a; #设定系统时间 date -s "2023-11-16 22:30:00" #同步写入BIOS hwclock -w3、fdisk分区 rootheihei:~# …...

深度学习与深度强化学习

1. 深度学习中卷积层的作用是什么&#xff1f;全连接层的作用是什么&#xff1f;二者有什么联系和区别&#xff1f; 在深度学习中&#xff0c;卷积层&#xff08;Convolutional Layer&#xff09;和全连接层&#xff08;Fully Connected Layer&#xff09;是神经网络中常见的两…...

C++函数重载中形参是引用类型和常量引用类型的调用方法

void fun(int &a) {cout<<"调用func(int &a)<<endl; }void fun(const int &a) {cout<<"调用func(const int &a)<<endl; }int main() {// 1.调用引用类型的函数int a10;func(a);// 2.调用常量引用类型的函数&#xff0c;因为…...

Quest 3期间Sui上游戏处理了数百万笔交易

Sui固有的可扩展性和低且可预测的gas费使其成为Web3游戏的理想平台。在Quest 3中&#xff0c;参与的游戏项目处理了数百万笔交易&#xff0c;这毫无疑问地展示了Sui卓越的能力。 Quest 3的主题是游戏&#xff0c;让开发者有机会向潜在玩家介绍他们激动人心的创作。鼓励这些玩家…...

Python中如何定义类、基类、函数和变量?

在Python中&#xff0c;定义类、基类、函数和变量是非常常见的操作。以下是简单的示例&#xff1a; 定义类&#xff1a; class Animal:def __init__(self, name):self.name namedef make_sound(self):passclass Dog(Animal):def make_sound(self):return "Woof!"上…...

打开文件 和 文件系统的文件产生关联

补充1&#xff1a;硬件级别磁盘和内存之间数据交互的基本单位 OS的内存管理 内存的本质是对数据临时存/取&#xff0c;把内存看成很大的缓冲区 物理内存和磁盘交互的单位是4KB&#xff0c;磁盘中未被打开的文件数据块也是4KB&#xff0c;所以磁盘中页帧也是4KB&#xff0c;内存…...

【Rust】快速教程——模块mod与跨文件

前言 道尊&#xff1a;没有办法&#xff0c;你的法力已经消失&#xff0c;我的法力所剩无几&#xff0c;除非咱们重新修行&#xff0c;在这个世界里取得更多法力之后&#xff0c;或许有办法下降。——《拔魔》 \;\\\;\\\; 目录 前言跨文件mod多文件mod 跨文件mod //my_mod.rs…...

crontab定时任务是否执行

centos查看 crontab 是否启动 systemctl status crond.service 查看cron服务的启动状态 systemctl start crond.service 启动cron服务[命令没有提示] systemctl stop crond.service 停止cron服务[命令没有提示] systemctl restart crond.service 重启cron服务[命令没有提示] s…...

MATLAB程序设计:牛顿迭代法

function xnewton(x0,e,N,fx) %输入x0,误差限e,迭代次数N和函数Fx k1; while k<Nif subs(diff(fx),x0)0disp("输出奇异标志");break;endx1x0-subs(fx,x0)/subs(diff(fx),x0);if abs(x1-x0)<ebreak;endx0x1;kk1; end if k<Ndisp(x1); elsedisp("迭代失败…...

B031-网络编程 Socket Http TomCat

目录 计算机网络网络编程相关术语IP地址ip的概念InerAdress的了解与测试 端口URLTCP、UDP和7层架构TCPUDPTCP与UDP的区别和联系TCP的3次握手七层架构 Socket编程服务端代码客户端代码 http协议概念Http报文 Tomcat模拟 计算机网络 见文档 网络编程相关术语 见文档 IP地址 …...

gRPC之metadata

1、metadata 服务间使用 Http 相互调用时&#xff0c;经常会设置一些业务自定义 header 如时间戳、trace信息等&#xff0c;gRPC使用 HTTP/2 协议自然也是支持的&#xff0c;gRPC 通过 google.golang.org/grpc/metadata 包内的 MD 类型提供相关的功能接口。 1.1 类型定义 /…...

【OpenCV实现图像:OpenCV进行OCR字符分割】

文章目录 概要基本概念读入图像图像二值化小结 概要 在处理OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;时&#xff0c;利用传统的图像处理方法进行字符切分仍然是一种有效的途径。即便当前计算机视觉领域主导的是卷积神经网络&#xf…...

景联文科技入选量子位智库《中国AIGC数据标注产业全景报告》数据标注行业代表机构

量子位智库《中国AIGC数据标注产业全景报告》中指出&#xff0c;数据标注处于重新洗牌时期&#xff0c;更高质量、专业化的数据标注成为刚需。未来五年&#xff0c;国内AI基础数据服务将达到百亿规模&#xff0c;年复合增长率在27%左右。 基于数据基础设施建设、大模型/AI技术理…...

ClickHouse SQL操作

基本上来说传统关系型数据库&#xff08;以MySQL为例&#xff09;的SQL语句&#xff0c;ClickHouse基本都支持&#xff0c;这里不会从头讲解SQL语法只介绍ClickHouse与标准SQL&#xff08;MySQL&#xff09;不一致的地方。 1 Insert 基本与标准SQL&#xff08;MySQL&#xff09…...

Ubuntu安装Python环境(使用VSCode)

想在Ubuntu上安装Python环境&#xff0c;选择了VSCode&#xff0c;而不想多装Anaconda等环境&#xff0c;最后参考了这篇博客&#xff1a; python入门开发:ubuntu下搭建python开发环境(vscode)...

QTcpSocket发送结构体的做法

作者&#xff1a;朱金灿 来源&#xff1a;clever101的专栏 为什么大多数人学不会人工智能编程&#xff1f;>>> QTcpSocket发送结构体其实很简单:使用QByteArray类对象进行封装发送&#xff0c;示例代码如下&#xff1a; /* 消息结构体 */ struct stMsg {int m_A…...

微服务学习 | Ribbon负载均衡、Nacos注册中心、微服务技术对比

Ribbon负载均衡 负载均衡流程 负载均衡策略 通过定义IRule实现可以修改负载均衡规则&#xff0c;有两种方式&#xff1a; 1. 代码方式:在服务消费者order-service中的OrderApplication类中&#xff0c;定义一个新的IRule: 2.配置文件方式: 在order-service的application.yml…...

【FPGA】zynq 单端口RAM 双端口RAM 读写冲突 写写冲突

RAMRAM读写分类RAM原理及实现RAM三种读写模式不变模式写优先读优先 单端口 RAM伪双端口 RAM真双端口 RAM读写冲突和写写冲突读写冲突写写冲突总结&#xff1a; RAM RAM 的英文全称是 Random Access Memory&#xff0c;即随机存取存储器&#xff0c;简称随机存储器&#xff0c;…...

【备忘】websocket学习之挖坑埋自己

背景故事 以前没有好好学习过websocket&#xff0c;只知道它有什么用途&#xff0c;也知道是个好东西&#xff0c;平时在工作中没用过&#xff0c;所以对它并不知所以然。如今要做个自己的项目&#xff0c;要在付款的时候实时播报声音。自己是个开发者&#xff0c;也不想用别人…...

大数据研发工程师面试

文章目录 面试1.AUC,ROC,准确率与召回率都是怎么计算的?2.数据清洗是如何清洗的&#xff0c;要做哪些清洗的工作&#xff1f;3.什么是数据的完整性?4.数仓是怎么设计的?5.linux查看进程的命令是什么&#xff0c;如何查看具体某一行的内容&#xff08;查看第n至m行&#xff0…...

【星海出品】云存储 ceph

https://ceph.com/en/ ceph组件介绍 Monitor 一个Ceph集群需要多个Monitor组成的小集群&#xff0c;它们通过Paxos同步数据&#xff0c;用来保存OSD的元数据。 OSD OSD全称Object Storage Device&#xff0c;也就是负责响应客户端请求返回具体数据的进程。一个Ceph集群一般都有…...

[nlp] grad norm先降后升再降

grad norm先降后升再降正常嘛 在深度学习中&#xff0c;梯度的范数通常被用来衡量模型参数的更新程度&#xff0c;也就是模型的学习进度。在训练初期&#xff0c;由于模型参数的初始值比较随机&#xff0c;梯度的范数可能会比较大&#xff0c;这是正常现象。随着模型的训练&…...

云积天赫AI全域营销系统,为品牌营销注入新活力

AIGC&#xff08;生成式人工智能&#xff09;的出现&#xff0c;标志着人工智能已经进入了一个全新的时代&#xff0c;它与传统的人工智能不同&#xff0c;可以更好地理解品牌的需求&#xff0c;并提供更精准的答案。目前&#xff0c;AIGC已经深入到各个领域&#xff0c;其中营…...

Arthas在线修改Java代码

Arthas在线修改Java代码 jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.javamc /tmp/UserController.java -d /tmpretransform /tmp/com/example/demo/arthas/user/UserController.class参考链接&#xff1a; arthas retransform...

mapbox支持的坐标系

mapbox 中只支持 web墨卡托坐标系&#xff0c;不支持经纬度坐标系。 栅格数据 基于经纬度坐标系的栅格数据没有办法渲染。矢量数据 矢量数据代码中会自动转换成墨卡托投影坐标系再渲染。 输出坐标时候还是经纬度。...

腾讯云新客户优惠服务器88元/年,540元/3年,另有5年优惠服务器

在选择云服务器时&#xff0c;首先需要考虑的是性能与配置是否与自己的需求相匹配。对于小型网站或者个人博客&#xff0c;轻量应用服务器是一个不错的选择。腾讯云双十一活动中&#xff0c;2核2G轻量应用服务器的活动优惠价为88元/年&#xff0c;2核4G轻量应用服务器的活动优惠…...

伦敦银和美白银的关系

与黄金相似&#xff0c;世界上白银交易的基础就是伦敦白银市场&#xff0c;人们利用设立在伦敦的专们负责清算银行&#xff08;与黄金的清算银行相同&#xff09;所开设的账户进行白银保证金交易。在伦敦市场&#xff0c;以美元清算的伦敦白银价格&#xff0c;是以美元买进1金衡…...

Matplotlib的使用方法

Matplotlib是Python最著名的绘图库&#xff0c;它提供了一整套和Matlab相似的命令API&#xff0c;十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件&#xff0c;嵌入到GUI应用程序中。Matplotlib能够创建多数类型的图表&#xff0c;如条形图、散点图、条形图、饼图…...