ACM学习历程7——Vector向量容量扩展机制
Vector向量容器相当于一个动态的数组,当向向量容器中不断加入元素,若超过容器本身的大小限制,vector会自动拓展大小,在这过程中涉及到内存的分配和回收。在vector中有size()和capacity()函数,与之相对应的两个函数resize(size_type)和reserve(size_type)。Size函数是指返回当前容器中的元素个数,对应的resize(size_type)会在容器
Vector向量容器相当于一个动态的数组,当向向量容器中不断加入元素,若超过容器本身的大小限制,vector会自动拓展大小,在这过程中涉及到内存的分配和回收。在vector中有size()和capacity()函数,与之相对应的两个函数resize(size_type)和reserve(size_type)。Size函数是指返回当前容器中的元素个数,对应的resize(size_type)会在容器尾添加或删除一些元素,来调整容器中实际的内容,使容器达到指定的大小。Capacity指最少要多少元素才会使其容量重新分配,对应reserve(size_type new_size)会置这个capacity值,使它不小于所指定的new_size。有了这两个函数,可以通过下面的代码来测试一下,缺省情况下Vector的扩展机制是怎样。
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
vector<int>::size_type tmp = 0;
ofstream ofs("resize.txt");
for (int i = 0, j = 1; i < 10000000; i++)
{
v.push_back(i);
if (v.capacity() != tmp)
{
cout << j << " " << v.capacity() << endl;
ofs << j << " " << v.capacity() << endl;
tmp = v.capacity();
j++;
}
}
return 0;
}
执行的结果如下:
从第二例数据可以看出,缺省情况下vector的扩展机制是按2倍拓展的也就是指数递增。在整个大小拓展的过程中,主要的步骤如下:
(1)为需要的新容量分配足够的内存;
(2)将元素从原来的内存拷贝到新内存中;
(3)销毁原来内存中的元素;
(4)归还原来的内存。
如果元素的数目为n,那么我们知道步骤(2)和(3)都要占用O(n)的时间,除非分配或归还内存的代价的增长超过O(n),否则这两步将在全部运行时间中占居支配地位。因此我们可以得出结论:无论用于重新分配的容量(capacity)是多少,重新分配一个 大小(size)为n的vector需要占用O(n)的时间。这个结论暗示了一种折衷权衡。假如在重新分配时请求大量的额外内存,那么在相当长的时间内将无需再次进行重新分配,因此总体重新分配操作消耗的时间相对较少,这种策略的代价在于将会浪费大量的空间。另一方面,我们可以只请求一点点额外的内存,这么做将会节约空间,但后继的重新分配操作将会耗费时间。换句话说,我们面临一个经典的抉择:拿时间换空间,或者拿空间换时间。当然在ACM题目的解答过程中,一般会告知数据的范围,这样我们可以定义vector容器的大小,即使没有告知数据量的大小,但是一定要避免陷入vector容器自增长造成内存空间的浪费。当然,当vector容量不够用的时候我们可以根据需要定义需要拓展的大小。
#include <iostream>
#include <vector>
using namespace std;
void showInfo(vector<int> &v)
{
int i;
for(i=0;i<v.size();i++)
cout<<v[i]<<" ";
cout<<endl;
}
int main()
{
vector<int> v;
int i;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
//此时v的实际大小
cout<<"size="<<v.size()<<endl;
showInfo(v);
//根据需要拓展大小
v.resize(10);
v.insert(v.begin()+4,5);
cout<<"size="<<v.size()<<endl;
showInfo(v);
return 0;
}
更多推荐
所有评论(0)