C++关于vector的详细介绍

这篇具有很好参考价值的文章主要介绍了C++关于vector的详细介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、vector的介绍

vector底层本质就是一个顺序表,它是一个可变长的数组,采用连续存储的空间来存储数据,它的元素类型也可以是任意的内置类型或者自定义类型。

c++ vector,C++,c++,算法,开发语言

二、vector的使用

1.vector的定义方式

第一种方式:定义一个任意类型的空vector

vector<int> v1;
vector<double> v2;
vector<string> v3;

第二种方式:定义一个任意类型的vector,并用n个val来初始化vector

vector<int> v4(10, 5);// 用10个5来初始化vector

第三种方式:定义一个任意类型的vector,并用迭代器区间来初始化vector

vector<int> v5(v4.begin(), v4.end());// 用v4的迭代器区间来初始化v5
string s("hello world");
vector<char> v6(s.begin(), s.end());// 用s的迭代器区间来初始化v6

2.vector的遍历

第一种方式:下标+[]循环遍历

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    vector<int> v(10, 10);
    for (size_t i = 0; i < v.size(); i++)
    {
        v[i] += i;
        cout << v[i] << " ";
    }
    cout << endl;
    return 0;
}

第二种方式:迭代器循环遍历

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    vector<int> v(10, 10);
    vector<int>::iterator it = v.begin();
    while (it != v.end())
    {
        (*it)++;
        cout << *it << " ";
    }
    cout << endl;
    return 0;
}

第三种方式:范围for遍历

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    vector<int> v(10, 10);
    for (auto i : v)
    {
        i++;
        cout << i << " ";
    }
    cout << endl;
    return 0;
}

3.利用vector实现二维数组

我们可以通过一个例子来了解如何通过vector实现二维数组,假设我们定义一个5*10的二维空数组,循环向二维数组写入值,最后循环打印这个二维矩阵。

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    vector<vector<int>> v;
    v.resize(5);// 开辟5行空间
    for (size_t i = 0; i < 5; i++)
    {
        v[i].resize(10);// 开辟10列空间
    }

    // 至此,5行10列的二维数组初始化完毕
    // 向二维数组写入
    for (size_t i = 0; i < v.size(); i++)
    {
        for (size_t j = 0; j < v[i].size(); j++)
        {
            v[i][j] = i*j;
        }
    }

    // 打印二维数组
    for (size_t i = 0; i < v.size(); i++)
    {
        for (size_t j = 0; j < v[i].size(); j++)
        {
            cout << v[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

4.vector的扩容机制

我们可以通过实验测试一下在Linux下vector是怎么扩容的,一次扩容扩大多少倍?我们定义一个vector,利用nowCapacity来记录vector的容量大小。循环向vector尾插100次数据,当vector的容量发生变化时,打印出来观察前后容量的变化情况。

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
    vector<int> v;
    size_t nowCapacity = v.capacity();
    cout << "nowCapacity:" << nowCapacity << endl;
    for (size_t i = 0; i < 100; i++)
    {
        v.push_back(i);
        if (nowCapacity != v.capacity())
        {
            nowCapacity = v.capacity();
            cout << "nowCapacity:" << nowCapacity << endl;
        }
    }
    return 0;
}

在Linux下的运行结果如下图所示,我们可以看到它是呈现2倍增长的。

c++ vector,C++,c++,算法,开发语言

相同的代码在VS编译器下实验最后的结果是呈1.5倍增长。其实vector一次扩容多少倍并没有确定的数值,一般就是1.5倍增长到2倍增长这样一个范围,因为如果单次增长较多那么增长的次数就会更少,效率也更高,但是如果单次增长过多容易造成空间浪费;如果单次增长较少那么增长的次数就会更多,效率也更低,但是不容易造成空间的浪费。

5.insert函数和erase函数

vector的insert函数不支持下标的方式去插入,只提供了借助迭代器完成插入的接口。

c++ vector,C++,c++,算法,开发语言

第一种方式:在指定迭代器的位置插入一个值

vector<int> v(10, 10);
v.insert(v.begin() + 3, 11);// 在第三个位置插入11

第二种方式:在指定迭代器的位置插入n个val值

vector<int> v(10, 10);
v.insert(v.begin() + 2, 5, 2);// 在第二个位置往后连续插入5个2

vector的erase函数也不支持下标的方式去删除,只提供了借助迭代器完成删除的接口。

c++ vector,C++,c++,算法,开发语言

第一种方式:删除指定迭代器位置的值

vector<int> v(10, 10);
v.erase(v.begin());// 删除第3个位置的值

第二种方式:删除迭代器区间内的所有值

vector<int> v(10, 10);
v.erase(v.begin() + 2, v.begin() + 6);// 删除第2个位置到第6个位置的所有值

6.迭代器失效问题

示例一:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    // 循环插入1,2,3,4,5,6到v中
    for (int i = 1; i <= 6; i++)
    {
        v.push_back(i);
    }
    // 在所有的偶数前面插入10
    vector<int>::iterator it = v.begin();
    while (it != v.end())
    {
        if ((*it) % 2 == 0)
        {
            v.insert(it, 10);
        }
        it++;
    }

    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;
    return 0;
}

上面的代码示例中,我们循环向数组中所有的偶数前插入10,会出现两种情况的迭代器失效:

第一种: 发生扩容时出现野指针问题

c++ vector,C++,c++,算法,开发语言

第二种:空间足够时不会出现扩容,但会出现无限插入的死循环问题
这种情况虽然没有出现扩容造成的野指针问题,但迭代器的指向意义已经改变了,这也是迭代器失效问题。

c++ vector,C++,c++,算法,开发语言

其实在标准库中vector的insert函数的实现是有返回值的,insert函数的返回值是新插入值位置的迭代器。

c++ vector,C++,c++,算法,开发语言

所以示例一的正确写法应该是下面这样的:每一次insert插入的时候都更新一下it的值,这样就可以避免扩容造成的野指针问题。然后每一次insert插入之后都需要对it进行加一操作,这样就可以避免死循环插入的问题。

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    // 循环插入1,2,3,4,5,6到v中
    for (int i = 1; i <= 6; i++)
    {
        v.push_back(i);
    }
    // 在所有的偶数前面插入10
    vector<int>::iterator it = v.begin();
    while (it != v.end())
    {
        if ((*it) % 2 == 0)
        {
            it = v.insert(it, 10);// v:1,10,2,3,4,5,6
            // 此时it指向的是10的位置
            it++;
        }
        it++;
    }

    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;
    return 0;
}

示例二:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    // 循环插入1,2,3,4,5,6到v中
    for (int i = 1; i <= 6; i++)
    {
        v.push_back(i);
    }
    // 在所有的偶数前面插入10
    vector<int>::iterator it = v.begin();
    while (it != v.end())
    {
        if ((*it) % 2 == 0)
        {
            v.erase(it);
        }
        it++;
    }

    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;
    return 0;
}

上面的代码也是迭代器失效的问题,它同样存在两种问题:

第一种:因为最后一个数也是偶数,当最后一个数被删除以后,it加一去到了v.end()的后一个位置,所以就会陷入死循环

c++ vector,C++,c++,算法,开发语言

第二种:数字3和5是没有被检测是否属于偶数的,因为删除了一个偶数之后,下一个数挪动到被删除的位置,然后执行it++操作,跳过了新数据的检测。

c++ vector,C++,c++,算法,开发语言

同样的,在标准库种vector的erase函数的实现是有返回值的,erase函数的返回值是被删除数据的位置。

c++ vector,C++,c++,算法,开发语言

所以示例二的正确写法应该是下面这样的:如果it当前指向的位置是偶数的话,直接erase函数删除该偶数,然后将返回值给it,it此时指向的就是被删除偶数的下一个数据,所以不需要再进行加一操作。如果it当前指向的位置是奇数的话,则进行加一操作。

#include <iostream>
#include <vector>

using namespace std;

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    // 循环插入1,2,3,4,5,6到v中
    for (int i = 1; i <= 6; i++)
    {
        v.push_back(i);
    }
    // 在所有的偶数前面插入10
    vector<int>::iterator it = v.begin();
    while (it != v.end())
    {
        // 如果是偶数,直接删除,将返回值给it
        // 此时it指向的就是被删除数据的下一个数据,所以不需要++
        if ((*it) % 2 == 0)
        {
            it = v.erase(it);
        }
        // 如果是奇数,再进行++
        else
        {
            it++;
        }
    }

    for (auto e : v)
    {
        cout << e << " ";
    }
    cout << endl;
    return 0;
}

所以,vector的迭代器失效问题是很容易发生的,我们在使用的时候一定要非常非常小心。一定要画图动态地模拟它的变化,再针对不同的迭代器失效问题使用对应的解决方法。文章来源地址https://www.toymoban.com/news/detail-739627.html

到了这里,关于C++关于vector的详细介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】vector的介绍与使用

      🧑‍🎓 个人主页:简 料   🏆 所属专栏:C++   🏆 个人社区:越努力越幸运社区   🏆 简       介: 简料简料,简单有料~在校大学生一枚,专注C/C++/GO的干货分享,立志成为您的好帮手 ~ C/C++学习路线 (点击解锁) ❤️ C语言 ❤️ 初阶数据结构与算法 ❤️ C++ ❤️

    2024年02月04日
    浏览(43)
  • [C++]vector的介绍及使用

    目录 C++:vector的使用                 1.vector的定义方式                 2.vector的空间增长                         size和capacity                         reserve和resize                         empty                 3.ve

    2024年02月08日
    浏览(45)
  • 【C++】STL---vector基本用法介绍

    个人主页:平行线也会相交💪 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C++之路】💌 本专栏旨在记录C++的学习路线,望对大家有所帮助🙇‍ 希望我们一起努力、成长,共同进步。🍓 vector 是 C++STL 中的一种 动态数组容器 ,用于存储和

    2024年02月16日
    浏览(46)
  • 【C++】——vector的介绍及模拟实现

    上一篇文章我们学习了C++中string类的使用和模拟实现,string是一种表示字符串的字符串类今天我们来继续学习C++中的另一种容器:vector。 1.vector是表示可变大小数组的序列容器。 2.就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元

    2024年02月08日
    浏览(34)
  • C++中的vector的详细用法

    目录 C++中的vector的详细用法 一、vector的介绍 二、存储类型 三、函数 四、vector二维数组两种方法 五、vector中find()用法 六、vector的访问 七、vector中insert()函数增加元素操作 八、vector中erase()函数删除元素操作 头文件:#include vector 向量(Vector)是一个封装了动态大小数组的顺

    2024年02月06日
    浏览(42)
  • C++:关于模拟实现vector和list中迭代器模块的理解

    本篇是关于 vector 和 list 的模拟实现中,关于迭代器模块的更进一步理解,以及在前文的基础上增加对于反向迭代器的实现和库函数的对比等 本篇是写于前面模拟实现的一段时间后,重新回头看迭代器的实现,尤其是在模板角度对 list 中迭代器封装的部分进行解析,希望可以

    2024年02月07日
    浏览(44)
  • c++算法——vector

            vector 是标准模板库的一个容器,直接翻译为“向量”,一般来成“可变长数组”,也即“长度会根据需要而变化的数组”。在竞赛中有些题目需要很大的很大的数组,而有些还用不上就需要用到 vector 。         使用 vector 首先要加#include vector,当然万能头也

    2023年04月24日
    浏览(48)
  • 【C++初阶】第九站:vector的介绍及使用

    前言: 🎯个人博客:Dream_Chaser 🎈博客专栏:C++ 📚本篇内容:vector的介绍及使用 ​ 目录 一、vector的介绍 二、vector的使用 1.vector的定义 2.vector iterator(迭代器)的使用 begin和end(正向迭代器) rbegin和rend(反向迭代器) 3.vector 空间增长问题 size和capacity max_size reserve和resize empty 4.ve

    2024年04月25日
    浏览(34)
  • C++面试:向量vector和列表list介绍

    目录 vector list  list和vector的区别 1. 底层实现: 2. 动态性和静态性: 3. 内存管理: 4. 迭代器和指针: 5. 访问效率: 6. 适用场景:   std::vector 是 C++ STL 提供的动态数组容器,提供了多种操作。以下是一些常见的 std::vector 操作,一一列举出来 初始化和基本操作 插入和删除元

    2024年01月22日
    浏览(33)
  • c++ vector用法 入门必看 超详细

    vector是最常用的容器之一,功能十分强大,可以储存、管理各种类型的数据。在很多情况下可以用来代替功能比较局限的普通数组,因为我们知道,普通数组只能实现一对一的映射而不能实现一对多的映射,vector就是专门为了解决这个问题而诞生的。vector也可以称为动态数组

    2024年02月01日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包