讨论顺序表

讨论顺序表

  • C++中的`vector`
  • 模拟实现
    • 成员变量
    • 尾插数据`push_back`
      • 扩容`reserve`
    • 构造函数和析构函数
    • 拷贝构造函数
    • 指定位置插入数据
    • 指定位置删除数据
    • 迭代器失效
    • 完整代码

C++中,vector是可以改变大小的数组的序列容器。可以看做底层就是一个数组,容量满时扩容。

C++中的vector

  • C++标准库中的vector是个模板类,可以存放不同数据类型的数据。
vector<int> v1;
vector<string> v2;
vector<double> v3;
vector<vector<int>> v4;

模拟实现

成员变量

  • 采用底层是数组模拟实现vector,参考stl_vector源码

  • protected:typedef simple_alloc<value_type, Alloc> data_allocator;iterator start;iterator finish;iterator end_of_storage;
    
  • 使用指针指向数组起始位置,结束位置下一个以及容量位置。

template<class T>
class vector {
private:iterator _first;iterator _finish;iterator _end_of_storage;
};

尾插数据push_back

扩容reserve

  • 插入数据,首先还是需要判断容量是否满足条件。_finish == _end_of_storage即容量已满,需要扩容。
  • 防止浅拷贝,就不能拷贝地址空间,需要再次动态申请空间。
void reserve(size_t n) {if(n > capacity()) {T* tmp = new T[n];size_t len = size();if(_first) {for (size_t i = 0; i < len; ++i) {tmp[i] = _first[i];}delete[] _first;}_first = tmp;_finish = _first + len;_end_of_storage = _first + n;}
}
void push_back(const T& val) {// 判断扩容if(_finish == _end_of_storage) {reserve(capacity() == 0 ? 5 : 2 * capacity());}*_finish = val;++_finish;
}

构造函数和析构函数

构造函数

  • 针对初始化n个元素的构造函数,可以复用尾插push_back函数。
vector() {}vector(size_t n, const T &val = T()) {reserve(n);for (size_t i = 0; i < n; ++i) {push_back(val);}
}
  • 析构函数只需要释放_first所指向的空间即可。
~vector() {delete[] _first;_first = _finish = _end_of_storage = nullptr;
}

拷贝构造函数

  • 同样复用尾插push_back即可。
vector(const vector<T> &v) {reserve(v.capacity());for (auto &e: v) {push_back(e);}
}
  • 赋值构造。
vector<T> &operator=(vector<T> tmp) {swap(tmp);return *this;
}
  • 迭代器构造函数
template<class InputIterator>
vector(InputIterator first, InputIterator last) {while(first != last) {push_back(*first);++first;}
}

指定位置插入数据

  • 指定位置插入数据不仅要判断容量,还需要判断位置是否满足要求,需要在_first_finish之间。
iterator insert(iterator pos, const T &x) {assert(pos >= _first);assert(pos <= _finish);// 判断容量if (_finish == _end_of_storage) {size_t len = pos - _first;reserve(capacity() == 0 ? 5 : 2 * capacity());pos = _first + len; // 防止异地扩容时,pos位置失效}iterator end = _finish - 1;while (end >= pos) {*(end + 1) = *end;--end;}*pos = x;++_finish;return pos;
}

指定位置删除数据

iterator erase(iterator pos) {assert(pos >= _first);assert(pos < _finish);iterator start = pos;while (start < _finish - 1) {*start = *(start + 1);++start;}--_finish;return pos;
}

迭代器失效

  • 在特定位置插入或者删除元素时,都有可能造成迭代器失效。
  • 如在插入数据时,如果不对pos位置做检查,异地扩容后还在原有pos位置插入数据,则数据无效,因此需要重新检查pos位置是否有效。
  • 而在删除元素时,如果循环删除特定数据,随着元素的移动,迭代器也会失效导致结果不正确,因此在编写指定位置删除数据的代码时,设定返回删除数据下一个位置的迭代器,来解决迭代器失效问题。
max::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(2);
v.push_back(3);
v.push_back(9);
v.push_back(6);auto it = v.begin();
while(it != v.end()) {if(*it % 2 == 0) {it = v.erase(it);} else {++it;}
}for(int n : v) {cout << n << " ";
}
cout << endl;

删除数据结果

完整代码

namespace max {template<class T>class vector {public:typedef T *iterator;typedef const T *const_iterator;vector() {}vector(size_t n, const T &val = T()) {reserve(n);for (size_t i = 0; i < n; ++i) {push_back(val);}}vector(int n, const T &val = T()) {reserve(n);for (int i = 0; i < n; ++i) {push_back(val);}}template<class InputIterator>vector(InputIterator first, InputIterator last) {while(first != last) {push_back(*first);++first;}}void swap(vector<T> &v) {std::swap(_first, v._first);std::swap(_finish, v._finish);std::swap(_end_of_storage, v._end_of_storage);}vector(const vector<T> &v) {reserve(v.capacity());for (auto &e: v) {push_back(e);}}vector<T> &operator=(vector<T> tmp) {swap(tmp);return *this;}~vector() {delete[] _first;_first = _finish = _end_of_storage = nullptr;}iterator begin() {return _first;}iterator end() {return _finish;}const_iterator begin() const {return _first;}const_iterator end() const {return _finish;}void resize(size_t n, const T &val = T()) {if(n <= size()) {_finish = _first - n;} else {reserve(n);while(_finish < _first + n) {*_finish = val;++_finish;}}}void reserve(size_t n) {if (n > capacity()) {T *tmp = new T[n];size_t len = size();if (_first) {for (size_t i = 0; i < len; ++i) {tmp[i] = _first[i];}delete[] _first;}_first = tmp;_finish = _first + len;_end_of_storage = _first + n;}}void push_back(const T &val) {// 判断扩容if (_finish == _end_of_storage) {reserve(capacity() == 0 ? 5 : 2 * capacity());}*_finish = val;++_finish;}void pop_back() {assert(size() >= 0);--_finish;}iterator insert(iterator pos, const T &x) {assert(pos >= _first);assert(pos <= _finish);// 判断容量if (_finish == _end_of_storage) {size_t len = pos - _first;reserve(capacity() == 0 ? 5 : 2 * capacity());pos = _first + len; // 防止异地扩容时,pos位置失效}iterator end = _finish - 1;while (end >= pos) {*(end + 1) = *end;--end;}*pos = x;++_finish;return pos;}iterator erase(iterator pos) {assert(pos >= _first);assert(pos < _finish);iterator start = pos;while (start < _finish - 1) {*start = *(start + 1);++start;}--_finish;return pos;}T &operator[](size_t pos) {return _first[pos];}const T &operator[](size_t pos) const {return _first[pos];}size_t size() const {return _finish - _first;}size_t capacity() const {return _end_of_storage - _first;}private:iterator _first = nullptr;iterator _finish = nullptr;iterator _end_of_storage = nullptr;};
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android集成高德地图SDK(1)

1.新建Android应用&#xff0c;确定应用包名 2.注册高德开放平台&#xff0c;打开控制台页面&#xff0c;应用管理&#xff0c;我的应用&#xff0c;创建新应用 3.添加Key 4.获取SHA1码 找到Android Studio自带的keytool 将其拖到cmd中&#xff0c;输入命令 -v -list -keystor…

【单片机毕业设计选题24024】-房间自动除湿控制系统

系统功能: 系统分为手动和自动模式&#xff0c;上电默认为自动模式。自动模式下如果获取到湿度 值大于设定的湿度值则自动打开风扇&#xff0c;手动模式下手动开关风扇。 系统上电后显示“欢迎使用除湿控制系统请稍后”&#xff0c;两秒钟后进入主页面显示。 第一行显示系统…

Python-矩阵元素定位

[题目描述] 小理得到了一个 n 行 m 列的矩阵&#xff0c;现在他想知道第 x 行第 y 列的值是多少&#xff0c;请你帮助他完成这个任务。输入格式&#xff1a; 第一行包含两个数 n 和m &#xff0c;表示这个矩阵包含 n行 m 列。从第 2 行到第 n1 行&#xff0c;每行输入 m 个整数…

KLayout ------ 旋转物体90度并做平移

KLayout ------ 旋转创建的物体 正文正文 前段时间,有个小伙伴留言问我,KLayout 中如何旋转自己创建的物体,这里特来说明一下。 import pyapoly = pya.DPolygon([pya.DPoint(0, 0), pya.DPoint(0, 5), pya

聚观早报 | 荣耀Magic V Flip开售;亚马逊将升级Alexa

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 6月24日消息 荣耀Magic V Flip开售 亚马逊将升级Alexa HarmonyOS NEXT Beta发布 懂车帝上线独家片场计划 苹果正…

基于堆叠长短期记忆网络 Stacked LSTM 预测A股股票价格走势

前言 系列专栏:【深度学习&#xff1a;算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域&#xff0c;讨论了各种复杂的深度神经网络思想&#xff0c;如卷积神经网络、循环神经网络、生成对…

羊大师:拒绝心灵内耗:走向高效与平和

在繁忙的生活中&#xff0c;我们时常感到疲惫不堪&#xff0c;仿佛心灵被无形的枷锁束缚&#xff0c;这就是精神内耗。它让我们在思考、决策和行动中犹豫不决&#xff0c;消耗着我们的精力和时间&#xff0c;让我们无法专注于真正重要的事情。然而&#xff0c;我们有能力打破这…

HCIP-数通 V1.0 培训教材总结01

HCIP-数通 V1.0 培训教材总结01 01 认识网络设备框式设备及其硬件模块盒式设备框式、盒式设备的区别网络设备逻辑架构网络设备对报文的处理流程 01 认识网络设备 框式设备及其硬件模块 S12700E-8 &#xff08;S-switch&#xff0c;交换机) &#xff08;8&#xff0c;业务槽位…

Redis通用命令详解

文章目录 一、Redis概述1.1 KEYS&#xff1a;查看符合模板的所有 key1.2 DEL&#xff1a;删除一个指定的 key1.3 EXISTS&#xff1a;判断 key 是否存在1.4 EXPIRE&#xff1a;给一个 key 设置有效期&#xff0c;有效期到期时该 key 会被自动删除1.5 TTL&#xff1a;查看一个 ke…

VPDBVE16E、VPDBVE32A、VPDBVE32B比例控制阀放大器

VPDBPC06A、VPDBPC06B、VPDBPC06C、VPDBPC06D、VPDBPC06E、VPDB08PC06100、VPDB08PC06200、VPDB08PC06315、VPDBVE16A、VPDBVE16B、VPDBVE16C、VPDBVE16D、VPDBVE16E、VPDBVE32A、VPDBVE32B、VPDBVE32C、VPDBVE32D、VPDBVE32E、VPDM2VE16A、VPDM2VE16B、VPDM2VE16C、VPDM2VE16D…

AWS中国IAM用户强制使用MFA

问题 需要对IAM用户强制使用MFA方式进行登陆。 步骤 创建强制MFA登陆策略 找到策略创建入口&#xff0c;如下图&#xff1a; 将下述内容json策略内容&#xff0c;复制到编辑器里面&#xff0c;具体内容和操作如下&#xff1a; {"Version": "2012-10-17&qu…

笔记-python之celery使用详解

Celery是一个用于处理异步任务的Python库&#xff0c;它允许你将任务分发到多个worker进行处理。以下是Celery的使用详解&#xff1a; 安装Celery 使用pip安装Celery&#xff1a; pip install celery创建Celery实例 首先&#xff0c;需要创建一个Celery实例&#xff0c;指定b…

Centos7 Docker部署PgSQL

拉取镜像 docker pull postgres:14.7运行容器 docker run --restartalways --nethost --shm-size"2g" --name pgsql -v /home/postgresql/data/pgdata:/var/lib/postgresql/data -v /etc/localtime:/etc/localtime -e POSTGRES_PASSWORDtest2023 -d postgres:14…

手机归属地查询查询-手机归属地查询接口-手机归属地查询API

接口地址&#xff1a;https://www.wapi.cn/api_detail/59/166.html 在线查询&#xff1a;https://www.wapi.cn/mobile_area.html 网站地址&#xff1a;https://www.wapi.cn 返回格式&#xff1a;json,xml 请求方式&#xff1a;POST,GET POST 请求需要设置Header头&#xff1a;C…

力扣刷题笔记

记录5-6月力扣刷题&#xff0c;持续刷题中~ 2024.05 15.三数之和 双指针或者哈希表&#xff0c;注意去重的操作要考虑仔细 class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {vector<vector<int>> result;sort…

什么是多态?一文彻底搞懂!

什么是多态 面向对象程序设计有三要素&#xff1a;封装、继承&#xff08;或组合&#xff09;、多态&#xff0c;前两者较好理解&#xff0c;多态总让人困惑&#xff0c;不知道具体有什么作用&#xff0c;更不知道为什么要用多态。今天就来详细分析下什么是多态&#xff0c;以…

众所周知,配置即代码≠基础设置即代码

​前段时间翻到几条留言&#xff0c;问&#xff1a; “配置即代码和基础设施即代码一样吗&#xff1f;” “配置即代码是什么&#xff1f;怎么都是基础设施即代码&#xff1f;” 我们都是知道&#xff0c;DevOp的快速发展&#xff0c;让服务器管理与配置的时间大大减少&#x…

玩客云刷海纳思(记录下踩坑过程)

一、准备材料 1、硬件&#xff1a; 玩客云设备 至少1台&#xff0c;带电源线&#xff1b; USB公对公线&#xff0c;1条&#xff08;可网购或者自制&#xff0c;百度自制usb公对公就好了&#xff09;&#xff1b; 带usb2.0接口的电脑&#xff0c;1台&#xff0c;大部分电脑都…

基于 ROS 的 Terraform 托管服务轻松部署文本转语音系统 ChatTTS

介绍 ChatTTS是专门为对话场景设计的文本转语音模型&#xff0c;例如LLM助手对话任务。它支持英文和中文两种语言。最大的模型使用了10万小时以上的中英文数据进行训练。ChatTTS webUI & API 为 ChatTTS 提供了网页界面和API服务。 资源编排服务&#xff08;Resource Orc…

应用分发也叫APP分发

应用分发&#xff08;App Distribution&#xff09;或APP分发&#xff0c;通常指的是将移动应用程序&#xff08;如iOS、Android或其他平台的应用&#xff09;通过各种渠道提供给最终用户进行下载和安装的过程。这个过程涉及多个环节&#xff0c;包括应用开发、测试、发布、推广…