当前位置:首页 » 《关注互联网》 » 正文

【C++】:vector容器的基本使用

10 人参与  2024年05月24日 14:41  分类 : 《关注互联网》  评论

点击全文阅读


目录

?1,vector的介绍?2,vector的使用?2.1 vector的构造?2.2 vector iterator 的使用?2.3 vector 空间增长问题?2.4 vector 增删查改?2.5 vector 访问及遍历?2.6 vector实例化string类的初始化形式?2.7 sort算法的使用

?1,vector的介绍

vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list统一的迭代器和引用更好。

?2,vector的使用

vector学习时一定要学会查看文档:vector的文档介绍vector在实际中非常的重要,在实际中我们熟悉常见的接口就可以,下面列出了哪些接口是要重点掌握的。

注意:使用vector要包含 < vector >

?2.1 vector的构造

我们先介绍使用两个重点的构造使用,其余两个在下一篇模拟实现的文章中会涉及。

在这里插入图片描述

代码演示:

void TestVector1(){    //无参构造    vector<int> v1;         //构造并用4个100初始化    vector<int> v2(4, 100);//拷贝构造    vector<int> v4(v3);         //用迭代区间初始化                          vector<int> v3(second.begin(),second.end());                          }

?2.2 vector iterator 的使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码演示:

void TestVector2(){// 使用push_back插入4个数据vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);// 使用迭代器进行遍历打印vector<int>::iterator it = v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;// 使用迭代器进行修改it = v.begin();while (it != v.end()){*it *= 2;++it;}// 使用反向迭代器进行遍历再打印// vector<int>::reverse_iterator rit = v.rbegin();auto rit = v.rbegin();while (rit != v.rend()){cout << *rit << " ";++rit;}cout << endl;PrintVector(v);}

?2.3 vector 空间增长问题

在这里插入图片描述

代码演示1:

reisze(size_t n, const T& data = T())
将有效元素个数设置为n个,如果时增多时,增多的元素使用data进行填充。
注意:resize在增多元素个数时可能会扩容

void TestVector3(){vector<int> v;//插入一些数据for (int i = 1; i < 10; i++)v.push_back(i);v.resize(5);v.resize(8, 100);v.resize(12);cout << "v contains:";for (size_t i = 0; i < v.size(); i++)cout << ' ' << v[i];cout << '\n';}

代码演示2:

往vecotr中插入元素时,如果大概已经知道要存放多少个元素,可以通过reserve方法提前将容量设置好,避免边插入边扩容效率低。

void TestVectorExpandOP(){vector<int> v;size_t sz = v.capacity();//提前将容量设置好,可以避免一遍插入一遍扩容v.reserve(100);   cout << "making bar grow:\n";for (int i = 0; i < 100; ++i) {v.push_back(i);if (sz != v.capacity()){sz = v.capacity();cout << "capacity changed: " << sz << '\n';}}}

注意:

capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。
这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。resize在开空间的同时还会进行初始化,影响size。

?2.4 vector 增删查改

在这里插入图片描述

注意:insert和erase会涉及迭代器失效问题,这个问题比较复杂,将在vector的模拟实现里介绍。

代码演示1:

// 尾插和尾删:push_back/pop_backvoid TestVector4(){vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);auto it = v.begin();while (it != v.end()) {cout << *it << " ";++it;}cout << endl;v.pop_back();v.pop_back();it = v.begin();while (it != v.end()) {cout << *it << " ";++it;}cout << endl;}

代码演示2:

注意find不是vector自身提供的方法,是STL提供的算法。

// 任意位置插入:insert和erase,以及查找findvoid test_vector4(){vector<int> v1;v1.push_back(1);v1.push_back(25);v1.push_back(12);for (auto e : v1){cout << e << " ";}cout << endl;v1.insert(v1.begin(), 0);//头插for (auto e : v1){cout << e << " ";}cout << endl;v1.erase(v1.begin());//头删for (auto e : v1){cout << e << " ";}cout << endl;v1.insert(v1.begin() + 2, 50);//在中间位置插for (auto e : v1){cout << e << " ";}cout << endl;int x;cin >> x;//没有x就不插入,有x在它前面插入//find是算法里的函数 vector<int>::iterator pos = find(v1.begin(), v1.end(), x);if (pos != v1.end()){v1.insert(pos, 1000);}for (auto e : v1){cout << e << " ";}cout << endl;}

?2.5 vector 访问及遍历

// operator[]+index 和 C++11中vector的新式for+auto的遍历// vector使用这两种遍历方式是比较便捷的。void TestVector6(){vector<int> v{ 1, 2, 3, 4 };// 通过[]读写第0个位置。v[0] = 10;cout << v[0] << endl;// 1. 使用for+[]方式遍历for (size_t i = 0; i < v.size(); ++i)cout << v[i] << " ";cout << endl;// 2. 使用迭代器遍历cout << "swapv data:";auto it = swapv.begin();while (it != swapv.end()){cout << *it << " ";++it;}// 3. 使用范围for遍历for (auto x : v)cout << x << " ";cout << endl;}

?2.6 vector实例化string类的初始化形式

注意:
(1) 有名对象和匿名对象的使用形式的区别。

(2) 此时范围for的使用,最好加上const 和 &
因为范围for的底层其实是迭代器,* it 赋值给e,而这里的*it是string类,每次赋值都是深拷贝,所以加引用可以避免多余的拷贝构造,const是因为不修改。

void TestVector7(){vector<string> v1;//此时v1指向的就是对象数组//有名对象string s1("张三");v1.push_back(s1);//匿名对象v1.push_back(string("李四"));//直接单参数隐式类型转换v1.push_back("王五");//对名字进行修改v1[1] += "你好";//加const &//范围for的底层其实是*it赋值给e//而这里的*it是string类,每次赋值都是深拷贝for (const auto& e : v1){cout << e << " ";}cout << endl;}

?2.7 sort算法的使用

sort不在vector中,在STL的算法库中。

在这里插入图片描述

(1) sort算法默认排升序,它的参数需要传迭代器。

(2) 那如何控制升降序呢?根据sort的第二个重载,多了一个仿函数的参数。就是下面代码中的greater(降序),less(升序)。其实这两个也是模板,再用这个模板进行实例化对象。并且又重载了operator() 运算符

void TestVector8(){//sort算法的使用vector<int> v1;v1.push_back(1);v1.push_back(25);v1.push_back(12);v1.push_back(9);v1.push_back(0);v1.push_back(40);//默认排升序greater<int> gt1;//降序 >less<int> gt2;//升序 <//重载了operator()cout << gt1(3, 4) << endl;//0cout << gt1.operator()(3, 4) << endl;//全部排序//有名对象使用//sort(v1.begin(), v1.end(),gt1);//匿名对象使用sort(v1.begin(), v1.end(), greater<int>());//去头去尾排//sort(v1.begin() + 1, v1.end() - 1);//对前一半排序//sort(v1.begin(), v1.begin() + v1.size() / 2);for (auto e : v1){cout << e << " ";}cout << endl;}

点击全文阅读


本文链接:http://zhangshiyu.com/post/112909.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1