vetor和array类似,都是普通数组的“升级版”,但array实现的时静态数组(长度固定),而vector实现的时一个动态数组,即可以进行元素的插入和删除。

一、调用方法

  1. #include <vector>
  2. using namespace std;

二、vector支持的迭代器的成员函数

image.png

C++ 11 新添加的 begin() 和 end() 全局函数也同样适用于 vector 容器。即当操作对象为 vector 容器时,其功能分别和表 1 中的 begin()、end() 成员函数相同。

迭代器的具体功能示意图
image.png

vector使用中的问题

容量(capacity)和大小(size)的区别

image.png

  • size返回当前实际的元素个数,即vector的大小,
  • capacity返回容量大小,可以通过reserce修改
  • vector 容器的大小不能超出它的容量,在大小等于容量的基础上,只要增加一个元素,就必须分配更多的内存。注意,这里的“更多”并不是 1 个。换句话说,当 vector 容器的大小和容量相等时,如果再向其添加(或者插入)一个元素,vector 往往会申请多个存储空间,而不仅仅只申请 1 个
  • 一旦 vector 容器的内存被重新分配,则和 vector 容器中元素相关的所有引用、指针以及迭代器,都可能会失效,最稳妥的方法就是重新生成

    emplace_back()和push_back()的区别

    emplace_back() 和 push_back() 的区别,就在于底层实现的机制不同。push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程

    insert()成员函数的语法格式

    image.png

    删除元素的几种方式

    image.png

    三、代码中的使用

    ```cpp

    include

    include

    include

    include

using namespace std;

int main() { /创建并初始化vector容器 / //1、创建空的vector,vt.size()==0 vector vt;

  1. //2、指定初始值和元素个数
  2. vector<int> primes{1, 2, 3, 4};
  3. //3、创建含有20个元素的vector,默认初始值都是0
  4. vector<int> pri1(20);
  5. vector<int> pri2(10, 5); //创建含有10个元素的vector,初始值都是5
  6. int a = 5, b = 10;
  7. vector<int> pri3(a, b); //两个个参数也可以通过变量来指定初始值
  8. //4、通过元素类型相同的vector来初始化
  9. vector<char> value1(5, 'c');
  10. vector<char> value2(value1); //value1和value2一样,都是具有5个元素,且初始值都是'c'
  11. int arr[] = {1, 2, 3};
  12. vector<int> value3(arr, arr+2); //value3将保存{1,2}
  13. vector<int> value4{1, 2, 3, 4, 5};
  14. vector<int> value5(value4.begin(), value4.begin()+3); //value5保存{1,2,3}
  15. /************************************************************/
  16. /*在容器中插入元素*/
  17. vector<int> vt1;
  18. //1、在尾部插入一个元素
  19. vt1.push_back(1);
  20. //2、在尾部插入一个元素,C++11新增成员函数,比push_back效率高
  21. vt1.emplace_back(3);
  22. //3、在头部插入一个元素
  23. vt1.insert(vt1.begin(), 2);
  24. //4、inset成员函数,插入多个元素
  25. //4-1 iterator insert(pos,elem)
  26. //在迭代器 pos 指定的位置之前插入一个新元素elem,并返回表示新插入元素位置的迭代器
  27. vector<int> iv{1, 2};
  28. iv.insert(iv.begin(), 8); //{1, 8, 2}
  29. //4-2 iterator insert(pos,n,elem)
  30. //在迭代器 pos 指定的位置之前插入 n 个元素 elem,并返回表示第一个新插入元素位置的迭代器
  31. iv.insert(iv.end(), 2, 5); //{1, 8, 2, 5, 5}
  32. //4-3 iterator insert(pos,first,last)
  33. //在迭代器 pos 指定的位置之前,插入其他容器(不仅限于vector)中位于 [first,last) 区域的所有元素,并返回表示第一个新插入元素位置的迭代器
  34. array<int, 3> arr0{7, 8, 9};
  35. iv.insert(iv.end(), arr0.begin(), arr0.end()); //{1, 8, 2, 5, 5, 7, 8, 9}
  36. //4-4 iterator insert(pos,initlist)
  37. //在迭代器 pos 指定的位置之前,插入初始化列表(用大括号{}括起来的多个元素,中间有逗号隔开)中所有的元素,并返回表示第一个新插入元素位置的迭代器
  38. iv.insert(iv.end(), {1, 2}); //{1, 8, 2, 5, 5, 7, 8, 9, 1, 2}
  39. //5、emplace成员函数
  40. //iterator emplace (const_iterator pos, args...);
  41. //emplace() 是 C++ 11 标准新增加的成员函数,用于在 vector 容器指定位置之前插入一个新的元素
  42. //emplace效率高于inset
  43. //强调,emplace() 每次只能插入一个元素,而不是多个
  44. vector<int> demo{1, 2};
  45. demo.emplace(demo.begin(), 3); //{3,1,2}
  46. /**********************************************/
  47. /*迭代器的用法*/
  48. //1、 begin() 和 end() 成员函数
  49. vector<int> val{1, 2, 3, 4, 5};
  50. auto first = val.begin();
  51. auto end = val.end();
  52. while (first != end)
  53. {
  54. cout<<*first<<" ";
  55. first++;
  56. }
  57. cout<<endl;
  58. //2、begin() 和 end() 函数
  59. auto first1 = begin(val);
  60. auto end1 = std::end(val);
  61. //3、cbegin()/cend() 成员函数
  62. //和 begin()/end() 唯一不同的是,前者返回的是 const 类型的正向迭代器
  63. vector<int> cval{1, 2, 3, 4, 5};
  64. auto cfirst = cval.cbegin();
  65. auto cend = cval.cend();
  66. while (cfirst != cend)
  67. {
  68. //*cfirst = 10; 不能修改元素
  69. cout<<*cfirst<<" ";
  70. }
  71. cout<<endl;
  72. //4、rbegin() 和 rend() 成员函数
  73. //分别表示指向最后一个元素和第一个元素前一个位置的随机访问迭代器
  74. vector<int> rval{1, 2, 3, 4, 5};
  75. auto rfirst = rval.rbegin();
  76. auto rend = rval.rend();
  77. while (rfirst != rend)
  78. {
  79. cout<<*rfirst<<" ";
  80. rfirst++;
  81. }
  82. //5、crbegin()/crend()成员函数
  83. //和 rbegin()/crend() 组合唯一的区别在于,前者返回的迭代器为 const 类型
  84. //6、对于空的 vector 容器来说,begin() 和 end() 成员函数返回的迭代器是相等的,即它们指向的是同一个位置
  85. //对于空的 vector 容器来说,可以通过调用 push_back() 或者借助 resize() 成员函数实现初始化容器的目的
  86. //7、vector 容器在申请更多内存的同时,容器中的所有元素可能会被复制或移动到新的内存地址,这会导致之前创建的迭代器失效
  87. vector<int> vv{1, 2, 3};
  88. cout<<"vv容器首个元素的地址: "<<vv.data()<<endl;
  89. auto vfirst = vv.begin();
  90. auto vend = vv.end();
  91. vv.reserve(10);
  92. cout<<"vv容器首个元素的地址: "<<vv.data()<<endl;
  93. /*********************************************************/
  94. /*删除元素*/
  95. //1、pop_back()
  96. //删除 vector 容器中最后一个元素,该容器的大小(size)会减 1,但容量(capacity)不会发生改变
  97. vector<int> vdel{1, 2, 3};
  98. vdel.pop_back();
  99. cout<<vdel.capacity()<<endl; //容量大小不变
  100. cout<<vdel.size()<<endl;//元素个数减一
  101. for (int k=0; k<vdel.size(); k++)
  102. cout<<vdel[k];
  103. //{1, 2}
  104. //2、erase(pos)
  105. //删除 vector 容器中 pos 迭代器指定位置处的元素,并返回指向被删除元素下一个位置元素的迭代器。该容器的大小(size)会减 1,但容量(capacity)不会发生改变
  106. vector<int> vdel1{1,2,3,4,5};
  107. auto itor = vdel1.erase(vdel1.begin()+1);
  108. cout<<vdel1.size()<<endl; //元素个数减一
  109. cout<<vdel1.capacity()<<endl; //容量大小不变
  110. cout<<*itor<<endl; //迭代器itor指向3的位置
  111. //3、swap(beg)、pop_back()
  112. //先调用 swap() 函数交换要删除的目标元素和容器最后一个元素的位置,然后使用 pop_back() 删除该目标元素
  113. //swap() 函数在头文件 <algorithm> 和 <utility> 中都有定义,使用时引入其中一个即可
  114. vector<int> vdel2{1,2,3,4,5};
  115. //3-1交换要删除元素和最后一个元素的位置
  116. swap(*(std::begin(vdel2)+1),*(std::end(vdel2)-1)); //等同于swap(vdel2[1],vdel2[4])
  117. //删除最后一个元素
  118. vdel2.pop_back();
  119. //4、删除容器中某个指定区域内的所有元素
  120. //iterator erase (iterator first, iterator last);
  121. //first 和 last 是指定被删除元素区域的迭代器,同时该函数会返回指向此区域之后一个位置的迭代器
  122. vector<int> vdel4{1,2,3,4,5};
  123. //删除2,3
  124. vdel4.erase(vdel4.begin()+1, vdel4.end()-2);
  125. cout<<vdel4.size()<<endl; //元素个数减2
  126. cout<<vdel4.capacity()<<endl; //容量大小不变
  127. //5、remove() 函数
  128. //删除容器中和指定元素值相同的所有元素
  129. vector<int> vdel5{1,2,3,4,3,5};
  130. auto iter = remove(vdel5.begin(), vdel5.end(), 3);
  131. cout<<vdel5.size()<<endl; //6
  132. cout<<vdel5.capacity()<<endl; //6
  133. vdel5.erase(iter, vdel5.end());
  134. cout<<vdel5.size()<<endl; //4
  135. cout<<vdel5.capacity()<<endl; //6
  136. //remove() 的实现原理是,在遍历容器中的元素时,一旦遇到目标元素,就做上标记,然后继续遍历,直到找到一个非目标元素,即用此元素将最先做标记的位置覆盖掉,同时将此非目标元素所在的位置也做上标记,等待找到新的非目标元素将其覆盖。因此,如果将上面程序中 demo 容器的元素全部输出
  137. //6、clear成员函数
  138. //删除容器中所有的元素
  139. vector<int> vdel6{1,2,3};
  140. vdel6.clear();
  141. cout<<vdel6.size()<<endl; //0
  142. cout<<vdel6.capacity()<<endl; //3
  143. /**********************************************/
  144. /*访问元素*/
  145. vector<int> vtt{1, 2, 3, 4, 5};
  146. //1、下标访问,跟数组访问方法一样
  147. cout<<vtt[0]<<endl;
  148. //2、at() 成员函数
  149. //索引会造成越界时,会抛出std::out_of_range异常
  150. cout<<vtt.at(0)<<endl;
  151. //3、front() 和 back()成员函数
  152. //分别返回 vector 容器中第一个和最后一个元素的引用
  153. vtt.front() = 10; //修改元素
  154. cout<<vtt.front()<<endl;
  155. cout<<vtt.back()<<endl;
  156. //4、data() 成员函数
  157. //返回指向容器中首个元素的指针
  158. *(vtt.data()+2) = 19;
  159. cout<<*(vtt.data()+2)<<endl;
  160. //5、访问vector容器中多个元素
  161. //借助 size() 成员函数,返回 vector 容器中实际存储的元素个数
  162. for (int i=0; i<vtt.size(); i++)
  163. {
  164. cout<<vtt[i]<<endl;
  165. }
  166. /********************************************/
  167. /*容量(capacity)和大小(size)的区别*/
  168. //vector 容器的容量(用 capacity 表示),指的是在不分配更多内存的情况下,容器可以保存的最多元素个数;
  169. //容器的大小(用 size 表示),指的是它实际所包含的元素个数
  170. //对于一个 vector 对象来说,通过该模板类提供的 capacity() 成员函数,可以获得当前容器的容量;通过 size() 成员函数,可以获得容器当前的大小
  171. vector<int> v{1, 2, 3, 4, 5};
  172. v.reserve(20); //修改v的容量大小
  173. cout<<v.capacity()<<endl; //容量大小是 20
  174. cout<<v.size()<<endl; //元素个数大小 5
  175. /************************************************/
  176. cout<<primes.size()<<endl;
  177. cout << "Hello World!" << endl;
  178. return 0;

}

```