STL vector容器及其函数总结

STL

Posted by Youggls on May 4, 2020

STL vector容器及其函数总结

使用方法

#include<vector>
using std::vector

API

  • 构造函数

      vector<int> a; //空构造函数
      vector<int> b(a); // 拷贝构造
      vector<int> c(4, 5) // 长度为4,值为5的vector
      vector<string> d {"the", "frogurt", "is", "also", "cursed"}; // C++ 11提供的列表初始化
    
  • 访问

    • at(size_type pos),返回pos处的元素引用,若pos不在容器范围内,抛出std::out_of_range异常。

    • operator[](size_type pos),返回pos处元素引用,且不进行边界检查

    • front(),返回首个元素的引用。对于空容器上的调用front()操作是未定义行为(UB)。g++对于该行为会报段错误(Segmentation fault)。

    • back(),返回末尾元素的引用。空容器上调用同front()

    • T* data(),返回指向作为元素存储工作的底层数组的指针。指针满足范围 [data(); data() + size()) 始终是合法范围,即使容器为空(该情况下 data() 不可解引用)。

  • 修改

    • clear(),清除内容。注意,该函数调用后,size()的返回值会是0,但是capacity()的返回值不变。即不销毁内存空间。

    • insert(iterator pos, const T& value)在pos前插入value。

    • insert(iterator pos, size_type count, const T& value)在pos前插入T的count个副本。

    • erase(iterator pos),移除位于pos处的元素。

    • erase(iterator first, iterator last),移除[first,last)中的元素

      注意,移除了元素之后,迭代器指向的位置会发生改变。例如[1,2,3,4],迭代器本来指向2,然后2被移除后,该迭代器会指向3。

    • push_back(const T& value),初始化新元素为value的副本,然后将value推入末尾。若新的 size() 大于 capacity() ,则所有迭代器和引用(包含尾后迭代器)都被非法化。否则仅尾后迭代器被非法化。

    • pop_back()移除容器的最末元素。在空容器上调用 pop_back 是未定义的。非法化指向末元素的迭代器和引用,以及 end() 迭代器。

    • resize(size_type count)重设容器大小以容纳 count 个元素。若当前大小大于 count ,则减小容器为其首 count 个元素。

    • swap(vector& other)将内容与 other 的交换。不在单个元素上调用任何移动、复制或交换操作。

  • 容量

    • empty()检查是否为空,即begin() == end()

    • size()返回元素个数,注意返回值类型为size_t,即unsigned int,如果大于INT_MAX时赋值给int会出现问题

    • void reserve(size_type new_cap)增加 vector 的容量到大于或等于 new_cap 的值。若 new_cap 大于当前的 capacity() ,则分配新存储,否则该方法不做任何事。reserve() 不更改 vector 的 size 。

    • capacity()返回容器之前已经分配的空间大小

  • 内置迭代器

    • begin()end()

    • rbegin()rend()

    YEvocT.png 例,该程序会逆序输出ints。注意迭代器的类型。

      #include <iostream>
      #include <vector>
      #include <string>
    
      int main()
      {
          std::vector<int> ints {1, 2, 4, 8, 16};
          std::vector<int>::reverse_iterator  it = ints.rbegin();
          for (;it != ints.rend(); it++) std::cout << *it << std::endl;
      }
    

一些关于vector的知识

  1. vector随机访问、在末尾插入元素都是O(1)的时间复杂度

  2. vector随机插入、移除元素,复杂度为O(N)

  3. vector内部维护的是数组而非链表

  4. 自C++11起的自动类型推导和for each遍历能够节约代码量

vector<int> ints{1,2,3,4,5}
for (auto x: ints) std::cout << x;