C++面向对象(OOP)编程-快速理解容器vector

本文主要介绍C++的STL模板中的vector的理解,主要包括常用的一些使用和三种vector的扩容方法的对比。

🎬个人简介:一个全栈工程师的升级之路!
📋个人专栏:C/C++精进之路
🎀CSDN主页 发狂的小花
🌄人生秘诀:学习的本质就是极致重复!

目录

1 vector 快速介绍

2 vector的三种扩容方法的区别

2.1 vec.resize(n)

2.2 vec.reserve(n)

2.3 vec.assign(n,0)

3 vector 使用例子

4 运行结果

5 vector和普通数组的区别


1 vector 快速介绍

         vector是C++ STL中的一个动态数组容器,相比于静态数组,vector的优势是可以动态改变其大小。C++使用时仅仅包含其头文件<vector>即可使用。

        vector 是一个类模板,本质上是一个动态变长数组即顺序表,元素的类型是任意的内置或者自定义的类型,存储在连续的存储空间,访问的时间复杂度为O(1),对于尾部元素的插入和删除时间复杂度都是常量级别的。

        对于vector的扩容机制,Linux一般是以2的倍数增加,VS一般是以1.5的倍数增加,增加快的性能会比较好,但是对空间的浪费会较大,一般可以使用 vec.resize(size) 进行扩容。vector扩容是开辟一段新的空间,将旧的数据拷贝到新的空间,因此对于数据量较大的场景,持续的扩容会极大的降低程序的性能。

        直接可以运行的代码我放在gitee 中,一些C++例子和高性能算法

2 vector的三种扩容方法的区别

2.1 vec.resize(n)

        vec.resize(n) resize的扩容不会改变容器中原来的值,这里默认对扩容的部分初始化为0

n > capacity 时 ,可以对vector进行扩容,此时 size = capacity = n,n 为任意的大于原来capacity的值

n < capacity 时,不能对vector进行扩容,此时 size = n,但是 capacity 仍然与原来的capacity 相等

2.2 vec.reserve(n)

        vec.reserve(n) 是指将容器的容量改为n,容器中的数据的个数不做改变也就是,不会对vec.size() 做改变

n > capacity 时 ,可以仅仅对容器进行扩容,此时size保持不变,capacity = n

n < capacity 时 ,不做任何的改变,对size 和capacity没有任何影响

2.3 vec.assign(n,0)

        vec.assign(n,0) assign的扩容会改变容器中原来的值,第二个参数就是需要改变后的值

n > capacity 时 ,可以对vector进行扩容,此时 size = capacity = n,n 为任意的大于原来capacity的值

n < capacity 时,不能对vector进行扩容,此时 size = n,但是 capacity 仍然与原来的capacity 相等

总之,对于vector容器只能增大其容量,不能减小其容量


3 vector 使用例子

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> vec = {1, 2, 3, 4, 5};
    // vec.begin()+2 代表从第三个元素开始,vec。begin()代表从第一个元素开始
    std::vector<int> vec1(vec.begin() + 2, vec.end()); // = vec
    std::vector<int> vec2(vec);                        // = vec
    std::vector<int> vec3(4);                          // [0,0,0,0]
    std::vector<int> vec4(2, 4);                       // [4,4]
    // vec.erase(vec.begin()+1); // 删除第二个元素
    vec.erase(vec.begin(), vec.begin() + 1); // 删除[1,3) 删除两个元素

    for (auto i : vec1)
    {
        std::cout << i << " ";
        std::cout << "*******" << std::endl;
    }

    vec.push_back(18); // 在尾部插入一个元素
    std::cout << "Front1: " << vec.front() << std::endl;

    std::cout << "Back1: " << vec.back() << std::endl;

    vec.pop_back(); // 弹出尾部的元素

    vec.insert(vec.begin() + 4, 3, 99);

    for (int i = 0; i < vec.size(); i++)
    {
        // std::cout << "vec(" << i << "): " << vec[i] << std::endl;

        std::cout << "vec(" << i << "): " << vec.at(i) << std::endl;
    }

    for (int i = 0; i < vec.size(); i++)
    {
        std::cout << i << " : " << vec.data()[i] << std::endl;
    }
    std::cout << "*********" << std::endl;
    std::vector<int>::iterator it;

    for (it = vec.begin(); it != vec.end(); it++)
    {
        std::cout << " "
                  << " : " << *it << std::endl;
    }
    std::cout << "*********" << std::endl;
    for (auto it = vec.begin(); it != vec.end(); it++)
    {
        std::cout << " "
                  << " : " << *it << std::endl;
    }
    std::cout << "*********" << std::endl;
    // 返回常量迭代器的元素
    for (auto it = vec.cbegin(); it != vec.cend(); it++)
    {
        std::cout << " "
                  << " : " << *it << std::endl;
    }
    std::cout << "*********" << std::endl;
    // 逆序返回常量迭代器的元素
    for (auto it = vec.rbegin(); it != vec.rend(); it++)
    {
        std::cout << " "
                  << " : " << *it << std::endl;
    }
    std::cout << "*********" << std::endl;
    std::cout << "size: " << vec.size() << " Capacity: " << vec.capacity() << std::endl;
    vec.clear();
    vec.resize(16); // 可以对vector进行扩容
    for (int i = 0; i < 10; i++)
    {
        vec.push_back(i);
    } // 需要对vector进行扩容,一般扩容是2的指数级别的
    std::cout << "After clear size: " << vec.size() << " Capacity: " << vec.capacity() << std::endl;
    if (vec.empty())
    {
        std::cout << "Vec is empty!" << std::endl;
    }
    std::vector<int> vecT[3]; // vector 定义二维数组
    for (int i = 0; i < 3; i++)
    {
        vecT[i].push_back(i);
        std::cout << "vecT" << i << " size: " << vecT[i].size() << std::endl;
    }
    std::vector<std::vector<int>> vecT1; // vector 定义二维数组
    vecT1.resize(5);                     // 5 行
    for (int i = 0; i < 5; i++)
    {
        vecT1[i].resize(10); // 10 列
    }
    for (int i = 0; i < vecT1.size(); i++)
    {
        for (int j = 0; j < vecT1[i].size(); j++)
        {
            vecT1[i][j] = i * j;
        }
    }

    for (int i = 0; i < vecT1.size(); i++)
    {
        for (int j = 0; j < vecT1[i].size(); j++)
        {
            std::cout << vecT1[i][j] << " ";
        }
    }
    std::cout << std::endl;
    return 0;
}

4 运行结果

3 *******
4 *******
5 *******
Front1: 2
Back1: 18
vec(0): 2
vec(1): 3
vec(2): 4
vec(3): 5
vec(4): 99
vec(5): 99
vec(6): 99
0 : 2
1 : 3
2 : 4
3 : 5
4 : 99
5 : 99
6 : 99
*********
  : 2
  : 3
  : 4
  : 5
  : 99
  : 99
  : 99
*********
  : 2
  : 3
  : 4
  : 5
  : 99
  : 99
  : 99
*********
  : 2
  : 3
  : 4
  : 5
  : 99
  : 99
  : 99
*********
  : 99
  : 99
  : 99
  : 5
  : 4
  : 3
  : 2
*********
size: 7 Capacity: 8
After clear size: 26 Capacity: 32
vecT0 size: 1
vecT1 size: 1
vecT2 size: 1
0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 0 2 4 6 8 10 12 14 16 18 0 3 6 9 12 15 18 21 24 27 0 4 8 12 16 20 24 28 32 36

5 vector和普通数组的区别

  1. 静态与动态:最显而易见的区别在于,数组的大小是静态的,这意味着一旦定义了数组的大小,就不能再更改。与此不同,vector是动态的,其大小可以在运行时进行修改,从而无需预先设定容量。

  2. 内存管理:数组在创建时需要在栈上或静态存储区中分配一段连续的内存空间,因此大小固定且无法更改。而vector则负责管理动态分配的内存,可以根据需要扩展或缩小内存空间。

  3. 性能差异:由于数组的内存分配是在编译时完成的,所以访问速度非常快。然而,如果vector需要重新分配更大的内存空间以容纳更多的元素,这个过程将涉及动态内存分配和释放,可能会比较耗时。

  4. 使用方法:尽管两者都支持随机访问和迭代器操作,但由于vector提供了更多的功能(如resize()、push_back()等),因此在使用时可能更为方便。

总的来说,选择使用vector还是普通数组主要取决于具体的需求和场景。例如,如果你需要一个可以动态改变大小的数据集,那么vector可能是更好的选择;反之,如果你需要一个访问速度快、大小固定的数据集,那么普通数组可能更适合你。

🌈我的分享也就到此结束啦🌈
如果我的分享也能对你有帮助,那就太好了!
若有不足,还请大家多多指正,我们一起学习交流!
📢未来的富豪们:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!最后,☺祝愿大家每天有钱赚!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发狂的小花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值