点击蓝字
关注我们
一、vector的介绍
说的简单点:vector是可以动态增长的数组容器
vector是表示可变大小数组的序列容器。
就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。
本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。
vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。。
因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好。
二、vector的使用
1、vector构造函数
void test1()
{vector<int> v1;//无参的构造用的最多vector<int> v2(10,1);//用10个1来初始化vector<int> v3(v2.begin(),v2.end());//用一段迭代器区间去初始化vector<int> v4(v3);//拷贝构造string s("hello");vector<char> v5(s.begin(), s.end());//不同STL的迭代器区间也可以初始化
}
结果展示:
打开监视窗口观察,确实初始化好了
问题:
对于下面这种情况,是不是差不多呢?能不能相互替代呢?
string s; 和 vector<char> v;
不行的!因为string末尾带着\0
,而且string提供了一些专门的字符串相关的接口函数,比如:operator+=,c_str,find等等函数
2、迭代器的使用
//vector中如何遍历
void test2()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);//下标[]遍历for (size_t i = 0; i < v.size(); ++i){v[i] += 1;cout << v[i] << " ";}cout << endl;//迭代器vector<int>::iterator it=v.begin();while (it != v.end()){cout << *it << " ";++it;}cout << endl;//反向迭代器vector<int>::reverse_iterator rit = v.rbegin();while (rit != v.rend()){cout << *rit << " ";++rit;}//范围forfor (auto e : v){cout << e << " ";}cout << endl;
}
3、空间增长问题
void test3()
{vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);cout << v.size() << endl;cout << v.capacity() << endl;cout << v.empty() << endl;cout << endl;v.reserve(100);//改变capacitycout << v.size() << endl;cout << v.capacity() << endl;cout << v.empty() << endl;cout << endl;v.resize(10,1);//改变size,默认给上缺省值0,它可以 扩容+初始化 或者 删除数据cout << v.size() << endl;cout << v.capacity() << endl;cout << v.empty() << endl;cout << endl;v.resize(2);cout << v.size() << endl;cout << v.capacity() << endl;cout << v.empty() << endl;cout << endl;
}
结果展示:
总结
capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,顺序表增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。
reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
resize在开空间的同时还会进行初始化,影响size。
4、增删查改问题
void test4()
{
vector<int> v;
//push_back尾插v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);//find查找
vector<int>::iterator ret = find(v.begin(), v.end(),3);
auto ret1 = find(v.begin(), v.end(), 3);
//可以用auto替换
if (ret != v.end()){
cout << "找到了" << endl;}v.insert(ret, 100);
for (auto e : v){
cout << e << " ";}vector<int>::iterator pos = find(v.begin(), v.end(), 1);
if (pos != v.end())//判断数据是否合法{
//erase删除v.erase(pos);}
cout << endl;
}
结果演示:
operator[ ] 和范围for是vector中常用的遍历手段
// vector使用这两种遍历方式是比较便捷的。
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int a[] = { 1, 2, 3, 4 };
vector<int> v(a, a + sizeof(a) / sizeof(int));// 通过[]读写第0个位置。v[0] = 10;
cout << v[0] << endl;// 通过[i]的方式遍历vector
for (size_t i = 0; i < v.size(); ++i)
cout << v[i] << " ";
cout << endl;vector<int> swapv;swapv.swap(v);
cout << "v data:";
for (size_t i = 0; i < v.size(); ++i)
cout << v[i] << " ";
cout << endl;cout << "swapv data:";
for (size_t i = 0; i < swapv.size(); ++i)
cout << swapv[i] << " ";
cout << endl;// C++11支持的新式范围for遍历
for (auto x : v)
cout << x << " ";
cout << endl;
return 0;
}
vector是支持迭代器的,还可以用范围for对vector进行遍历,支持迭代器就支持范围for,因为在编译时编译器会自动将范围for替换为迭代器遍历的形式。
*声明:本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。
戳“阅读原文”我们一起进步