C++---vector剖析与模拟实现
vector是定义于命名空间namespace std内的模板,头文件为#include< vector >
vector介绍
- vector表示可变大小的序列器
- vector采用连续的空间来存储数据,所以可以用下标来访问,其空间大小可以动态变化,所以类似于动态数组,因为支持随机访问,所以导致其效率低。
- vector使用动态分配数组来存储元素,每当容器满了,再插入需要进行扩容时,其会分配一个新数组,将全部元素转移过去,再进行插入操作。
vector接口整理
构造函数
函数声明 | 接口说明 |
---|---|
vector() | 无参构造函数 |
vector(size_type n,const T& val = T() | 构造并初始化n个val |
vector(Inputlterator first,Inputlterator last) | 用迭代器进行构造 |
vector(const vector& v) | 拷贝构造函数 |
vector<int> first(4, 10); //构造4个10vector<int> second(first); //拷贝构造函数int m[] = { 1,2,3,4,5 };vector<int> third(m, m + sizeof(m) / sizeof(m[0]));//使用迭代器初始化for (auto it : first){cout << it<<" ";}for (auto it : second){cout << it << " ";}for (auto it : third){cout << it << " ";}
vector迭代器
[begin,end)
iterator | 接口说明 |
---|---|
begin() | 获取数据的第一个位置 |
end() | 获取数据最后一个元素的下一个位置 |
rbegin()/rend() | 反向遍历 |
增删改查
增删改查 | 接口说明 |
---|---|
push_back() | 尾插 |
pop_back() | 尾删 |
_Pop_back_n(size_t n) | 尾删n个元素 |
find | 查找 |
insert() | 在pos位置前面插入 |
erase() | 删除pos位置上的元素 |
clear() | 清空容器 |
swap() | 交换数据空间 |
operator[ ] | 下标访问 |
push_back()与insert()的区别
push_back()将元素插到vector对象的末尾,insert()将元素插到vector对象的任意位置。
pop_back()尾删操作、erase()可以删除迭代器指定的元素,也可以删除一段区间、clear()删除vector对象的所有元素,类似于erase(begin(),end())
capacity操作
size() | 返回有效元素个数 |
---|---|
capacity() | 返回容器所能容纳的元素数 |
reserve() | 预设容器容量 |
resize() | 修改容器大小 |
empty() | 判空,if==nullptr 返回真 |
int a[] = { 1,2,3,4,5,6,7,8,9 };vector<int> v(a, a + sizeof(a) / sizeof(a[0]));//findauto pos = find(v.begin(), v.end(), 3);//insertv.insert(pos, 10);auto it = v.begin();while (it != v.end()){cout << *it << " ";it++;}//operator[] 范围forint a[] = { 1,2,3,4,5,6,7,8,9 };vector<int> v(a, a + sizeof(a) / sizeof(a[0]));v[0] = 10;for (auto e : v){cout << e <<" ";}
迭代器失效
//场景1 ---------因位置删除int a[] = { 1,2,3,4 };vector<int> v(a, a + sizeof(a) / sizeof(a[0]));auto pos = find(v.begin(),v.end(),3);//因为erase将pos位置的值删除v.erase(pos);//导致迭代器失效cout << *pos << endl;
//场景2 ---------因底层扩容int a[] = { 1,2,3,4 };vector<int> v(a, a + sizeof(a) / sizeof(a[0]));auto pos = find(v.begin(),v.end(),3);cout << v.capacity() << endl;//insert插入操作,导致底层扩容,但是pos依然指向扩容之前的位置,//但是已经被释放了,导致访问出错v.insert(pos, 5);v.insert(pos, 6);v.insert(pos, 7);
失效场景
- 所有可能导致底层空间改变的操作 push_back, resize, reaserve
- erase(it) 删除某个位置
解决办法:
重新给迭代器赋值
vector底层模拟实现
namespace bai
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;iterator begin()return _first;iterator end()return _end;const_iterator cbegin()return _first;const_iterator cend()return _end;vector():_first(nullptr), _end(nullptr), _endOfcapacity(nullptr){}vector(int n, const T& val = T()):_first(nullptr),_end(nullptr),_endOfcapacity(nullptr){reserve(n);while (n--){push_back(val);}}template<class T>vector(InputIterator start, InputIterator finish){reverse(finish - start);while (start != finish){push_back(*start);++start;}}vector(const vector<T>& v):_first(nullptr),_end(nullptr),_endOfcapacity(nullptr){reverse(v.capacity());iterator it = begin();const_iterator vit = cbegin();while (vit != cend()){*it++ = *vit++;}_end = _first + v.size();_endOfcapacity = _first + v.capacity();}vector& operator(const vector& v){Swap(v);return *this;}~vector(){delete[] _first;_first = _end = _endOfcapacity = nullptr;}void Swap(vector<T>& v){swap(_first, v._first);swap(_end, v, _end);swap(_endOfcapacity, v._endOfcapacity);}private:iterator _first; //指向数据块开头iterator _end; //指向数据块结尾iterator _endOfcapacity; //指向容量的尾部};
}
vector:如何创建一个二维数组:
vector<vector<int>> res;res.resize(3); //创建3行for (auto& e : res) //注意e.resize(4, 1);//给每行申请4个空间,默认初始化值为1
注意:当用vector创建二维数组时,给行申请空间时,最好写成引用,如果不写成引用,导致给行申请空间失败。
C++---vector剖析与模拟实现相关推荐
- 详解vector容器(应用+模拟实现,vector相关练习题)
vector容器 动态的顺序表,数组. vector操作 vector操作及其概念 构造 vector<int>v1;vector<int>v2(10, 5);vector&l ...
- C++ vector类的模拟实现
vector和string虽然底层都是通过顺序表来实现的,但是他们利用顺序表的方式不同,string是指定好了类型,通过使用顺序表来存储并对数据进行操作,而vector是利用了C++中的泛型模板,可以 ...
- 主成分分析(PCA)深入剖析+Matlab模拟
1.降维引发的思考 对于现在维数比较多的数据,我们首先需要做的就是对其进行降维操作.降维,简单来说就是说在尽量保证数据本质的前提下将数据中的维数降低.降维的操作可以理解为一种映射关系,例如函数z=f( ...
- 【C++】STL — vector的使用 + 模拟实现
文章目录
- Leetcode402 remove-k-digits贪心+vector模拟栈的思想
题目 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : 输入: ...
- vector之resize剖析-曾经的我以为自己真的学会了vector
vector之resize剖析 零.前言 一.先看下面一段代码 二.测试结果 三.测试代码 零.前言 曾经的我以为自己真的学会了vector!人的认知有限,就以为自己什么都会了.当你深入研究一下时,才 ...
- 学习笔记:C++初阶【C++入门、类和对象、C/C++内存管理、模板初阶、STL简介、string、vector、list、stack、queueu、模板进阶、C++的IO流】
文章目录 前言 一.C++入门 1. C++关键字 2.命名空间 2.1 C语言缺点之一,没办法很好地解决命名冲突问题 2.2 C++提出了一个新语法--命名空间 2.2.1 命名空间概念 2.2.2 ...
- c++ - 第9节 - vector类
目录 1.标准库中的vector类 1.1.vector类 1.2.vector类的常用接口说明 1.3.vector类练习题 2.vector类的模拟实现 2.1.vector类源代码解析 2.2. ...
- 冰冰学习笔记:反向迭代器的模拟
欢迎各位大佬光临本文章!!! 还请各位大佬提出宝贵的意见,如发现文章错误请联系冰冰,冰冰一定会虚心接受,及时改正. 本系列文章为冰冰学习编程的学习笔记,如果对您也有帮助,还请各位大佬.帅哥.美女点点支 ...
最新文章
- 联合国2019数字经济报告
- VC中的一些字符类型及其转换
- Android stutdio2.2 启动模拟器出现“/dev/kvm is not found.”解决方法
- 使用SSH+SFTP操作终端全解析,告别XShell
- 升级到VS.net 2008 sp1并安装卡巴斯基的兄弟们小心了
- 在颜值上,我 Bootstrap 真的没怕过谁
- Deeplab unexpected label
- java rhino 运行 js_Mozilla Rhino :如何从Java调用JS函数
- 作者:许方圆,男,国网能源研究院能源决策支持技术研发中心中级工程师。...
- LESS vs SASS?选择哪种CSS样式编程语言?
- Jar 包依赖冲突排查思路和解决方法(logback + slf4j-log4j12)
- 【渝粤教育】国家开放大学2018年春季 0630-22T环境法学 参考试题
- 【转】当你伤心时一定要读的50句话
- 算法复杂度与NP问题
- android命令行wifi开关,Android系统SVC命令(命令行WIFI开关、GPRS移动数据开关)
- matlab光学应用实践,Matlab在光学信息处理仿真实验中的应用
- 微信小程序:uni-app页面Page和组件Component生命周期执行的先后顺序
- element-plus 兼容低版本浏览器问题(uc内核 55)
- 旅行商问题(TSP)与局部搜索算法
- 给 iOS 开发者的 Flutter 指南
热门文章
- 重建控制文件--Rebuild controlfile
- marathon新建应用映射端口限制
- J2EE之初识JSP
- 【原创】Oracle RAC原理和安装
- 扬帆技术论坛系统封装工具 SPAT v 5.5.3.6_BETA1[官方最新版]
- 【实用工具】之CSDN表格模板
- 事件触发控制_基于事件触发机制的直流微电网多混合储能系统分层协调控制方法...
- 开发一个出生年份的下拉选择框供用户选择_关于下拉式菜单,这一篇足够了
- 如何使用python批量压缩图片_python利用Guetzli批量压缩图片
- 880 芯片组 服务器 cpu,顶级双核处理器对决 皓龙880完胜至强