• C++——vector


    目录

    vector

    vector常用接口

    构造函数

    operator[]+size()

    迭代器

    范围for

    capacity()

    resize()

    reverse()

    push_back和pop_back

    insert

     erase()

     algorithm::sort

    注意

    迭代器失效


    vector

            vector单词直译是向量的意思,这个容器可以容纳不同的类型数据,并且是一个连续的可自动增长的顺序表。

    1. // 它有两个模板参数,第一个就是vector要存放的类型,需要显示实例化
    2. // 第二个叫做空间配置器,如果不写,默认就是库中的
    3. template <class T, class Alloc = allocator> class vector;

    vector常用接口

    构造函数

    1. #include // 需要包含头文件
    2. vector<int> first; // 一个空vector,可以存放int
    3. vector<int> second (4,100); // 插入4个值为100的数据
    4. vector<int> third (second.begin(),second.end()); // 根据迭代器区间去构造
    5. vector<int> fourth (third); // 拷贝构造

    operator[]+size()

    1. reference operator[] (size_type n); // 返回值reference是返回的引用
    2. const_reference operator[] (size_type n) const; // 返回const引用
    3. size_type size() const; // 返回vector中的个数
    4. vector<int> v1(4, 100);
    5. for (int i = 0; i < v1.size(); i++) // 对每个值操作都是可以的
    6. {
    7. cout << v1[i] << " ";
    8. v1[i]++;
    9. }

    迭代器

    1. vector<int>::it = it.begin(); // 返回vector初始位置的指针
    2. while (it != v1.end()) // it不等于vector最后一个位置的下一个指针
    3. {
    4. (*it)++; // 这里有优先级的问题,一定要先解引用才可以拿到数据,否则迭代器就会先移动
    5. cout << *it << " ";
    6. it++;
    7. }
    8. // 还有其他迭代器使用方法是一样的

    范围for

    1. vector<int> v1(4, 100);
    2. for (auto e : v1) // 底层也是使用了迭代器
    3. {
    4. cout << e << " ";
    5. }

    capacity()

    size_type capacity() const; // 返回容器开辟的空间

    resize()

    1. void resize (size_type n, value_type val = value_type()); // 这个value_type就是显示实例化的那个模板参数
    2. vector<int> v1(4, 100); // resize有几种情况
    3. v1.resize(2); // 第一种,n < v1.size(),v1.size()会变成n,原来大于n的位置的数据会直接移除
    4. v1.resize(5, 1); // 第二种,n > v1.size(),v1.size()会变成n,并且没有初始化过的数据初始化为val
    5. v1.resize(10); // 第三种,n > v1.size(),没有给val的值,v1.size()会变成n,没有初始化过的值赋值为0
    6. // 以上三种如果vector空间不够会自动开辟空间,空间很大,size变得很小也会释放空间

    reverse()

    1. void reserve (size_type n); // 重新申请大小为n的空间
    2. // 如果n小于现在的capacity不操作,如果n大于capacity就重新申请大小为n的空间

    push_back和pop_back

    1. void push_back(const value_type& val); // 尾插
    2. void pop_back(); // 尾删
    3. // 不做过多介绍了

    insert

    1. void insert(iterator pos, size_type n, const value_type& val); // 传入一个迭代器,把val的值插入pos的位置
    2. void insert (iterator pos, InputIterator first, InputIterator last); // 在pos位置插入一段迭代器区间
    3. // string中还有find这样的函数还能找到下标,但是vector中并没有这个接口
    4. // 所以在algorithm这个库中就有这个函数
    5. template <class InputIterator, class T>
    6. InputIterator find (InputIterator first, InputIterator last, const T& val); // 在一段迭代器区间找到val
    7. vector<int> v(4, 1);
    8. vector<int>::iterator pos = find(v.begin, v.end(), 1);

     erase()

    1. iterator erase (iterator pos); // 删除pos位置
    2. iterator erase (iterator first, iterator last); // 删除一段区间
    3. vector<int> v(4, 1);
    4. vector<int>::iterator:: pos = find(v.begin(), v.end(), 1);
    5. if (pos != v.end()) // 这里最好还是判断一下,如果没找到就不删,不会报错
    6. {
    7. erase(pos);
    8. }

     algorithm::sort

    1. template <class RandomAccessIterator>
    2. void sort (RandomAccessIterator first, RandomAccessIterator last);
    3. // 这个函数虽然不是vector库中的,但还排序还是很好用的,它的底层是使用的快排
    4. // 这个函数默认排的是升序
    5. vector<int> v;
    6. v.push_back(2);
    7. v.push_back(1);
    8. v.push_back(7);
    9. v.push_back(4);
    10. sort(v.begin(). v.end());
    11. // 要是想要排降序呢
    12. template <class RandomAccessIterator, class Compare>
    13. void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
    14. // 前两个还是迭代器区间,最后一个参数决定是升序还是降序
    15. // 在库中有一个类模板less,把这个传入就是升序,也不需要传
    16. // 升序要再包含一个头文件functional,这样就可以使用greater这个类模板了
    17. sort(v.begin(), v.end(), greater<int>()); // 传入的是一个对象,所以使用匿名对象


    注意

    1. // vector不仅可以存放int,它甚至可以存放string
    2. vector strV;
    3. string str("abc");
    4. strV.push_back(str);
    5. strV.push_back(string("abc"));
    6. strV.push_back("abc");
    7. // 遍历
    8. for (auto& str : strV) // 这里注意的是,使用引用传参,如果不加引用就是深拷贝,深拷贝的代价很大
    9. {}


    迭代器失效

            迭代器也用过了,但是使用的过程中还会出现一些奇怪的问题。

    1. vector<int> v;
    2. v.push_back(1);
    3. v.push_back(2);
    4. v.push_back(3);
    5. vector<int>::iterator pos = find(v.begin(), v.end(), 3);
    6. if (pos != v.end())
    7. {
    8. v.insert(pos, 10);
    9. v.insert(pos, 20);
    10. }

    1. vector<int> v;
    2. v.push_back(1);
    3. v.push_back(2);
    4. v.push_back(3);
    5. v.push_back(4);
    6. auto it = v.begin();
    7. while (it != v.end())
    8. {
    9. if (*it % 2 == 0)
    10. erase(it);
    11. it++;
    12. }

    1. // 库中有这两个函数的声明,这里的返回值是操作后的下一个数,使用的时候一定要接受返回值
    2. iterator insert (iterator position, const value_type& val);
    3. iterator erase (iterator position);
    4. if (pos != v.end())
    5. {
    6. pos = v.insert(pos, 10);
    7. // 插入10,下一个位置就是3,扩容完之后pos的位置也是正确的
    8. pos = v.insert(pos, 20); // 再插入20就不会出错
    9. }
    10. while (it != v.end())
    11. {
    12. if (*it % 2 == 0)
    13. it = erase(it); // 这里不赋值也可以,如果删除了,it不动就是下一个的位置
    14. else
    15. it++; // 不删除再++
    16. }

            当然不止这两种实例可以证明迭代器失效,但是出的都是这一类问题,所以使用这两个函数的时候,一定要更新pos的位置,直接访问会出问题,这就是迭代器失效。迭代器失效的情况在不同平台下的效果是不一样的。

  • 相关阅读:
    “华为杯”研究生数学建模竞赛2015年-【华为杯】D题:面向节能的单/多列车优化决策问题
    java计算机毕业设计快递配送平台源码+系统+mysql数据库+lw文档+部署
    【禅道客户案例】同方智慧能源数智化转型新实践 禅道助力前行
    Kafka入门
    netty websockt之断连重试
    值得注意的: c++动态库、静态库、弱符号__attribute__((weak))以及extern之间的关系
    C++ string类(包括深浅拷贝)
    外汇天眼:美联储如预期再次加息75个基点 并誓言进一步加息以对抗通胀
    DBever SQL编辑器的高级应用:如何用变量快速查询
    PyQt5快速开发与实战 9.7 UI层的自动化测试
  • 原文地址:https://blog.csdn.net/m0_64607843/article/details/133799096