以下是阿鲤对vector的介绍和使用的总结,希望对大家有所帮助;若有误请慷慨指出。
1:vector的介绍
2:vector的使用
1:vector的介绍
首先我们看一下c++官网对vector介绍
Vectors are sequence containers representing arrays that can change in size.
Just like arrays, vectors use contiguous storage locations for their elements, which means that their elements can also be accessed using offsets on regular pointers to its elements, and just as efficiently as in arrays. But unlike arrays, their size can change dynamically, with their storage being handled automatically by the container.
Internally, vectors use a dynamically allocated array to store their elements. This array may need to be reallocated in order to grow in size when new elements are inserted, which implies allocating a new array and moving all elements to it. This is a relatively expensive task in terms of processing time, and thus, vectors do not reallocate each time an element is added to the container.
Instead, vector containers may allocate some extra storage to accommodate for possible growth, and thus the container may have an actual capacity greater than the storage strictly needed to contain its elements (i.e., its size). Libraries can implement different strategies for growth to balance between memory usage and reallocations, but in any case, reallocations should only happen at logarithmically growing intervals of size so that the insertion of individual elements at the end of the vector can be provided with amortized constant time complexity (see push_back).
Therefore, compared to arrays, vectors consume more memory in exchange for the ability to manage storage and grow dynamically in an efficient way.
Compared to the other dynamic sequence containers (deques, lists and forward_lists), vectors are very efficient accessing its elements (just like arrays) and relatively efficient adding or removing elements from its end. For operations that involve inserting or removing elements at positions other than the end, they perform worse than the others, and have less consistent iterators and references than lists and forward_lists.
翻译:
1. vector是表示可变大小数组的序列容器。
2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
6. 与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好
2:vector的使用
2.1:vector的定义(构造函数)
构造函数声明 | 接口说明 |
vector() | 无参构造 |
vector(size_ttype n, const value & val = value_type()) | 构造并初始化n个val |
vector(const vector&x) | 拷贝构造 |
vector(inputlterator first, inputlterator last) | 使用迭代器进行初始化构造 |
eg:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<char> arr;
vector<int> brr(5, 3);
vector<int> crr(brr);
vector<int> drr(brr.begin(), brr.end() - 1);
for (auto &i : arr)
{
cout << i << " ";
}
cout << endl;
for (auto &i : brr)
{
cout << i << " ";
}
cout << endl;
for (auto &i : crr)
{
cout << i << " ";
}
cout << endl;
for (auto &i : drr)
{
cout << i << " ";
}
cout << endl;
system("pause");
return 0;
}
结果:
2.2 vector iterator 的使用 (迭代器)
iterator的是使用 | 接口说明 |
begin() | 获取第一个数据位置的iterator |
end() | 获取最后一个数据的下一个位置的iterator |
rbegin() | 获取最后一个数据位置的reverse_iterator |
rend() | 获取第一个数据前一个位置的reverse_iterator |
cbegin() | 获取第一个数据位置的const_iterator |
cend() | 获取最后一个数据的下一个位置的const_iterator |
eg:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
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;
cout << *it << ' ';
++it;
}
cout << endl;
//使用反向迭代器
vector<int>::reverse_iterator rit = v.rbegin();
while (rit != v.rend())
{
cout << *rit << ' ';
++rit;
}
cout << endl;
system("pause");
return 0;
}
输出结果:
2.3:vector的空间增长问题
容量空间 | 接口说明 |
size() | 获取数据个数 |
capacity() | 获取容量大小 |
empty() | 判断是否为空 |
void resize(size_type n, value_type val = value_type()) | 改变vector的size |
void reserve(size_type n) | 改变vector中的容量 |
vector中容量的扩容方式和运行环境有关,以下是g++和vs2017两个环境中的扩容方式。
g++
#include<vector>
#include<iostream>
using namespace std;
int main()
{
vector<int> v;
for(int i = 0; i < 30; i++)
{
v.push_back(i);
cout << v.capacity() << " ";
}
cout << endl;
return 0;
}
结果
vs2017:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v;
for (int i = 0; i < 30; i++)
{
v.push_back(i);
cout << v.capacity() << " ";
}
cout << endl;
system("pause");
return 0;
}
结果:
有上面两个结果可以得出,在g++中,扩容是以二倍的方式进行的,而在vs2017中扩容方式是以1.5倍的方式增加的(最少扩容1);
2.4:vector的增删查改
vector增删查改 | 接口说明 |
void push_back(const value_type& val) | 尾插 |
void pop_back() | 尾删 |
iterator insert(iterator position , const value_type& val) | 在position之前插入val |
iterator erase(iterator position) | 删除position位置的数据 |
void swap(vector& x) | 交换两个vector的数据空间 |
reference operator[](size_type n) | 像数组一样访问 |
eg:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v;
vector<int> B;
B.push_back(999);
for (int i = 0; i < 10; i++)
{
v.push_back(i);//尾插
cout << v[i] << " ";
}
cout << endl;
v.pop_back();//尾删
for (auto &i:v)
{
cout << i << " ";
}
vector<int>::iterator it = v.begin();
v.insert(it + 5, 88);//在在position之前插入val
cout << endl;
for (auto &i : v)
{
cout << i << " ";
}
cout << endl;
v.erase(it + 3);//删除position为位置的数据
for (auto &i : v)
{
cout << i << " ";
}
cout << endl;
v.swap(B); //交换两个vector的数据空间
for (auto &i : v)
{
cout << i << " ";
}
cout << endl;
cout << v[0] << endl;//像数组一样访问
system("pause");
return 0;
}
输出结果:
2.5:迭代器失效问题
首先请看一段代码
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int a[] = { 1,2,3,4 };
vector<int> v(a, a + 4);
// 使用find查找3所在位置的iterator
vector<int>::iterator pos = find(v.begin(), v.end(),3);
//删除pos位置的数据,导致pos迭代器失效
v.erase(pos);
cout << (*pos) << endl;//会导致非法访问
system("pause");
return 0;
}
该代码会崩溃,因为在删除pos之后,再对pos进行访问会产生非法访问,从而使程序崩溃。
除了erase这个迭代器失效之外,还存在insert使迭代器失效
insert使迭代器失效的原因是,在insert时因为原空间的容量不够,要重新分配空间,从而使得原来的迭代器所指向的地方发生错误,产生非法访问。
那么怎样解决迭代器失效呢?
解决迭代器失效其实很简单,只需要用迭代器去接收使用迭代器函数的返回值即可,如下。
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int a[] = { 1,2,3,4 };
vector<int> v(a, a + 4);
// 使用find查找3所在位置的iterator
vector<int>::iterator pos = find(v.begin(), v.end(),3);
pos = v.erase(pos);//解决迭代器失效的方法。
cout << (*pos) << endl;
system("pause");
return 0;
}
好了,以上就是阿鲤对vector的简单介绍了;