• 【C++】一文带你走入vector



    ヾ(๑╹◡╹)ノ" 人总要为过去的懒惰而付出代价ヾ(๑╹◡╹)ノ"
    在这里插入图片描述


    一、vector的介绍

    vector文档介绍 大部分的使用与string的使用类似
    vector类似于顺序表,是动态增长的数组。头文件:#include < vector >

    1. vector是表示可变大小数组的序列容器。
    2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
    3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
    4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
    5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
    6. 与其它动态序列容器相比(deque, list and forward_list),vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list统一的迭代器和引用更好

    二、vector的常用接口说明

    2.1 vector的使用

    在这里插入图片描述
    vector可以存储任意类型的数据
    代码展示:

    	vector<int> v1;//可以是int类型,也可以是任意类型
    	v1.push_back(1);
    	v1.push_back(2);
    	v1.push_back(3);
    
    	vector<string> v2;//可以是string类型
    	v2.push_back("易烊千玺");
    	v2.push_back("王俊凯");
    	v2.push_back("王源");
    
    	vector<int> v3;
    	v3 = v1;
    
    	vector<double> v4(10, 1.2);//10个1.2进行初始化
    	//可以迭代器区间进行初始化
    	vector<string> v5(++v2.begin(), v2.end());
    	//从v2的第二个到最后一个,对v5进行初始化
    
    	string s = "hello world";
    	vector<char> v6(s.begin(), s.end());
    	//可以是任意类型的迭代器,不一定是自已类型的迭代器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意:allocator是空间配置器,其实就是内存池。空间配置器也可以自己写。
    在这里插入图片描述

    2.2 vector iterator的使用

    在这里插入图片描述

    vector的遍历

    	vector<int> v;
    	v.push_back(1);
    	v.push_back(2);
    	v.push_back(3);
    	v.push_back(4);
    	//vector的遍历
    	//1.[]
    	for (size_t i = 0; i < v.size(); i++)
    	{
    		cout << v[i] << " ";
    	}
    	cout << endl;
    	//2.迭代器
    	vector<int>::iterator it = v.begin();
    	while (it != v.end())
    	{
    		cout << *it << " ";
    		++it;
    	}
    	cout << endl;
    	//3.范围for
    	for (auto e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2.3 vector空间增长问题

    在这里插入图片描述
    max_size()
    在这里插入图片描述

    • capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。
    • reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
    • resize在开空间的同时还会进行初始化,影响size。(开空间+初始化可以用resize()
    • string 和 vector 删除数据时,是不会缩容的(capacity)

    单次增容越多,增容次数越少,效率就越高,但是可能浪费空间越多。(如果知道要开多少空间可以用reverve())

    shrink_to_fit
    在这里插入图片描述
    shink_to_fit会把容量变得和size一样,但是这个函数需要慎用,因为空间不是一部分还给操作系统,而是把所有空间都还给操作系统,重新开辟一块空间把数据放入。

    2.4 vector 增删查改

    在这里插入图片描述
    insert
    在这里插入图片描述
    vector是不支持下标插入的,只支持迭代器;string是支持下标插入的。
    vector是没有头插的,可以用insert进行头插。insert也支持尾插。【超过尾插就不可以了,就会越界访问,编译出现错误】

    	vector<int> v;
    	v.push_back(1);
    	v.push_back(2);
    	v.push_back(3);
    	v.push_back(4);
    	v.insert(v.begin(), -1);//相当于头插
    	for (auto e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    	v.insert(v.begin() + 5, 20);//相当于尾插
    	//v.insert(v.begin() + 7, 30);//这行代码,会报错
    	//此时一共有6个数据,如果在第8个位置插入是不可以的,不可以越界
    	for (auto e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述
    erase
    在这里插入图片描述
    注意:这里也是迭代器【注意:不能越界】

    查找
    vector和list都没有查找函数,复用的是算法里面的find()函数
    在这里插入图片描述

    find()函数支持一段迭代器区间找一个值,没有找到返回last.[所以,是一个前闭后开区间];头文件是#include < algorithm > 算法

    删除3->先找3这个位置->删除
    代码展示:

    	vector<int> v;
    	v.push_back(1);
    	v.push_back(2);
    	v.push_back(3);
    	v.push_back(4);
    	//查找
    	vector<int>::iterator pos = find(v.begin(), v.end(),3);
    	//auto pos = find(v.begin(), v.end(), 3);//这一种比较方便
    	if (pos != v.end())
    	{
    		cout << "找到了" << endl;
    		v.erase(pos);
    	}
    	else
    	{
    		cout << "没有找到" << endl;
    	}
    	for (auto e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述
    sort
    在这里插入图片描述

    • sort对vector可以进行排序,对其他容器也可以进行排序,但是有的并不适合(list)
    • sort默认是升序排序,如果想要降序,就需要仿函数【头文件#include < functional >】
      代码展示
    	vector<int> v;
    	v.push_back(1);
    	v.push_back(0);
    	v.push_back(5);
    	v.push_back(8);
    	v.push_back(4);
    
    	for (auto e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    	//默认升序
    	sort(v.begin(), v.end());
    	for (auto e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    	//仿函数,降序
    	sort(v.begin(), v.end(), greater<int>());
    	for (auto e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述


    三、总结

    以上就是今天要讲的内容,本文详细的介绍了vector的使用,vector iterator的使用,vector空间增长问题,vector增删查改。希望给友友们带来帮助!

  • 相关阅读:
    【手写数据库toadb】SQL解析器的实现架构,create table/insert 多values语句的解析树生成流程和输出结构分析
    中新赛克面试题汇总
    C语言实验十一 指针(一)
    【论文复现|智能算法改进】基于自适应动态鲸鱼优化算法的路径规划研究
    python re 使用非捕获组来忽略第一个value的匹配结果
    Qt多线程间信号槽传递非QObject类型对象的参数
    学员分享| 一个普通学员的HCIE-DATACOM备考之路!
    HTTPS协议原理
    Spring简单例子引入Spring要点
    vue3+vite配置svg文件的全局使用(想怎么改颜色、宽高都可以)
  • 原文地址:https://blog.csdn.net/m0_57388581/article/details/133395201