您的位置:首页 > 其它

STL入门教程一:vector的使用

2010-08-23 23:52 411 查看
vector应该说是在STL中使用最广泛的容器,也是本人最先学习和使用的STL内容O(∩_∩)O~。为什么vector会使用的非常广泛呢?大家知道,数组是几乎每一种语言都拥有的低级(不是不高级的意思哈,就是比较底层的意思O(∩_∩)O~)数据结构,在我们的工作中,我们会大量的使用数组来表示同一类事物的一个集合。而vector实质上就是一个可以存储任何元素的动态数组。vector虽然不是一个低级的数据结构,但是它各个操作的效率几乎是和数组相同的。只是它会使用比普通数组更多的空间。因为在vector因为空间不足而需要重新分配空间的时候,它一般会分配更多的空间(可能是当前size的1.5倍,这个是由具体实现定义的)。以免每次插入一个新的元素的时候,都会重新分配空间。重新分配空间是vector里面最没有效率的操作,所以大家在使用vector的时候要尽量避免重新分配空间。具体的方法是根据自己的实际需要来设定vector的capacity大小,这个我会在下面详细提到。关于分配空间,还有一点需要重新注意的是:vector一旦重新分配空间后,先前指向该vector的迭代器和引用都会变为无效的迭代器和引用。关于这一点,大家可以这样想,你使用new开辟了一个空间并不断使用元素填充这个空间。后来发现空间不够了,所以你就又重新new了一个更大的空间,并且将以前空间的所有元素拷贝了过去,最后释放了以前的空间。所以指向以前空间的指针(迭代器)和引用就无效了。下面就让我们来看一看vector的具体操作吧。

构造函数:

explicit vector (const Allocator& = Allocator());

默认构造函数,使用代码等价于

vector<int> v


explicit vector (size_type n, const T& value= T(), const Allocator& = Allocator())

用n个T类型的元素初始化vector,使用代码等价于

vector<int> v(3, 100)


template <class InputIterator> vector (InputIterator first, InputIterator last, const Allocator& = Allocator())

用迭代器first(包含)到last(不包含)之间的元素初始化Vector,使用代码如下

vector<int> v1(3,100);
vector<int> v2(v1.begin(),v2.end());


vector (const vector<T,Allocator>& x)

用相同类型的Vector初始化,相同类型的vector表示值类型相同并且分配器类型相同的vector,使用代码如下

vector<int> v1(3,100);
vector<int> v2(v1);


void push_back (const T& x)

添加值为x的元素到Vector的末尾,使用代码如下

vector<int> v;

for(int i = 0; i < 5; ++i)
{
v.push_back(i);
}

for(int i = 0; i < 5; ++i)
{
cout << v[i] << " ";
}

// output
// 1 2 3 4 5


iterator begin() const_iterator begin () const

iterator end () const_iterator end () const

获取指向vector开始和结尾的迭代器。请注意vector的结尾(end)迭代器并不是指vector的最后一个元素,而是该元素的后一个元素。该概念为所有的容器都通用的概念。使用代码如下

vector<int> v;

for(int i = 0; i < 5; ++i)
{
v.push_back(i);
}

vector<int>::iterator itb = v.begin();
vector<int>::iterator ite = v.end();
for(; itb != ite; ++itb)
{
cout << *itb << " ";
}

// output
// 1 2 3 4 5


reverse_iterator rbegin() const_reverse_iterator rbegin() const

reverse_iterator rend() const_reverse_iterator rend() const

vector<int> v;

for(int i = 0; i < 5; ++i)
{
v.push_back(i);
}

vector<int>::iterator ritb = v.rbegin();
vector<int>::iterator rite = v.rend();
for(; ritb != rite; ++itb)
{
cout << *ritb << " ";
}

// output
// 5 4 3 2 1


iterator insert ( iterator position, const T& x )

在迭代器position处插入值为x的元素,返回新位置的迭代器

void insert ( iterator position, size_type n, const T& x )

在迭代器position处插入n个值为x的元素

template <class InputIterator>
void insert ( iterator position, InputIterator first, InputIterator last )

在迭代器position处插入迭代器first(包含)和last(不包含)之间的元素

vector<int> v1;
v1.push_back(1);
v1.push_back(2);
vector<int>::iterator iter = v1.begin();
iter = v1.insert(iter, 3);

v1.insert(iter, 2, 4);

vector<int> v2;
v1.push_back(5);
v1.push_back(6);
v1.push_back(7);
iter = v1.begin();
vector<int>::iterator iterb = v2.begin();
vector<int>::iterator itere = v2.end();
v1.insert(iter, iterb, itere);

for(iter = v1.begin(), iter != v1.end(); ++iter)
{
cout << *iter << " ";
}

// output
// 5 6 7 4 4 3 1 2


对于insert操作,需要注意的是在vector执行该操作后,对于该vector以前的迭代器和引用都会失效

vector<int> v1;
v1.push_back(1);
v1.push_back(2);
vector<int>::iterator iter = v1.begin();
v1.insert(iter, 3);
for(; iter != v.end(); ++iter) // 错误, iter在insert后无效
{
cout << *iter << " ";
}


iterator erase ( iterator position )

删除迭代器postion处的元素,返回删除元素的后一个元素的迭代器

iterator erase ( iterator first, iterator last )

删除迭代器first(包含)到last(不包含)之间的元素,返回最后一个删除元素的后一个元素

vector<int> v;
for(int i = 0; i < 10; ++i)
{
v.push_back(i);
}

v.erase(v.begin() + 2);
v.erase(v.begin() + 3, v.begin() + 5);

vector<int>::iterator iter = v.begin();
for(; iter != v.end(); ++iter)
{
cout << *iter << " ";
}

// output
// 0 1 3 7 8 9


请注意,执行删除操作之后,在删除位置之后该vector先前的迭代器和引用就会变为无效。

size_type size() const

获取vector实际包含的元素数量

size_type capacity () const

获取vector所分配空间所能包含元素的数量

vector<int> v;
for (int i = 0; i < 10; ++i)
{
v.push_back(i);
}
cout << v.size() << " " << v.capacity();

// output
// 10 13
// 注意,capacity值可能会因为不同的编译器导致结果不同


在使用vector的时候,我们应该注意到这样一个问题,就是需要在vector中不断插入元素的时候。我们应该为vector设置一个重新分配时最少需要分配的元素值。通过这样的设置,我们可以减少vector中重新分配的次数,以使vector的使用达到比较高的效率。我们可以通过下面的函数来设置这个值。

void reserve (size_type n)

n为vector重新分配时vector至少要保留存放元素的个数。请注意当设置的n值大于vector的capacity值的时候,会引起vector进行重新分配。

vector<int> v;
v.reserve(20);
for (int i = 0; i < 10; ++i)
{
v.push_back(i);
}
cout << v.size() << " " << v.capacity();

// output
// 10 20


void resize (size_type sz, T c = T())

重新分配vector所占用的空间,如果sz小于当前size,则会截断sz之后的元素, 如果sz大于当前size,则会用c值补充。请注意,resize函数并不能改变由reserve函数所设置的值。这里还要提醒一句的是,所有resize的操作都会使先前指向该vector的指针和引用无效。

vector<int> v;
for(int i = 0; i < 10; ++i)
{
v.push_back(i);
]

v.resize(5);
v.resize(6, 7);
v,resize(10);

for(int i = 0; i < v.size(); ++i)
{
cout << v[i] << " ";
}

// output
// 1 2 3 4 5 7 0 0 0 0


vector的使用方法大概就是这些了,下一次为大家带来list的使用方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐