vector 总结

第一部分使用入门

vector可用于代替C中的数组,或者MFC中的CArray,从许多说明文档或者网上评论,一般一致认为应该多用vector,因为它的效率更高,而且具备很好的异常安全性。而且vectorSTL推荐使用的默认容器,除非你知道你有特殊需要,使用vector不能满足你的需求,例如需要容器在headtail高效的插入和删除,或者在任何位置高效的删除和插入操作,那么你可能使用deque或者list更加合适。

vector是连续内存容器,换句话说,标准要求所有标准库实现的时候,vector中的元素的内存必须是连续的。所以对于插入和删除的时间复杂度是很高的,因为删除或者插入的时候,需要元素的移动,即元素复制拷贝。

vector的内部实现一般需要用到placement new ,所以效率很高,因为很多的时候,只要我们是使用得到,就可以省去很多的内存分配开销。而且vector的使用,元素可以没有默认的构造函数,但是需要拷贝构造函数的存在,这是使用CArray所无法实现的。

使用原则:

1,尽量使用vector代替C风格的数组或者CArray

2,尽量使用算法代替手工写的循环;

3,尽量使用vector本身的函数代替其他泛型算法;

vector的接口很容易看懂和使用,这里以一些例子来说明vector的用法。

vector不会自动排序

1,填充vector

如果我们想用原始数组的内容填充vector,那么于有很多种方式。我们来一次学习vector的几个方法。

例如我们有数组int  v1[10] = {0,1,0,0,3,0,0,4,4,4};

初始化方式1:

vector<int> v2(10); //初始化size为10可以避免数组动态增长的时候不断的分配内存

//v2.reserve(10);//同上,只要使用其中一个就可以了

for( int i=0; i<10; i++ )

{

       v2.push_back(v1[i]);//增加一个元素

}

 

初始化方式2

vector<int> v3(&v1[0],&v1[9]);//原始数组的元素指针可以作为迭代器来使用

 

初始化方式3

vector<int> v4;

v4.reserve(10);

v4.insert(v4.begin(), &v1[0], &v[9]);

 

初始化方式4:

vector<int> v5(10);

copy(v5.begin(), &v1[0], &v1[9]);

原始数组的元素指针可以作为迭代器来使用。

 

原则:尽量使用reserve来减少不必要的内存分配次数。

原则:尽量使用empty而不是size()==0来判断容器是否为空


2,遍历vector

方式1

for( int i=0; i<v1.size(); i++ )

{

       print(v1[i]);

}

这种方式是我们最熟悉的,但是不够好,写起来不够简洁。而且对于没有随机迭代器的其他容器来说,这样做是办不到的。

 

方式2

typedef  vector<int>:: iterator   VIntIterator;

VIntIterator  end = v1.begin();

for( VIntIterator  i=v1.begin(); i != end;  ++i )

{

     print( *i );

}

#include<stdio.h>
#include<vector>
using namespace std;
int main()
{
    int n,i;
    vector<int>s(2);//可以节省分配的的时间
    while(scanf("%d",&n)!=EOF&&n)
    {
        s.push_back(n);
    }
    vector<int>::iterator it,end;
    end=s.end();//先记录下来  每次都计算s.end会浪费时间
    for(it=s.begin();it!=end;it++)
        printf("%d\n",*it);

    for(i=0;i<s.size();i++ )
        printf("%d\n",s[i]);
    return 0;  
}

注意:先计算 end 有好处,因为不必要每次去重复计算 end,vector end() 不是常数时间的,所以先缓存下来能提高效率。写算法的时候尽量使用 != 比较迭代器,因为 < 对于很多非随机迭代器没有这个操作符。

3vector中的删除

#include "iostream"
#include "vector"
using namespace std;
int   main()
{
    vector<int> arr;
    vector<int>::iterator it;
    arr.push_back(6);
    arr.push_back(8);
    arr.push_back(3);
    arr.push_back(8);
    for(it=arr.begin(); it!=arr.end();)
    {
        if(* it == 8)
        {
            it = arr.erase(it);//直接erase(8)是错误的  set中是可以的
        }
        else
        {
            ++it;
        }
    }
    cout << "After remove 8:\n";
    for(it = arr.begin(); it !=arr.end(); ++it)
    {
        cout << * it << " ";
    }
    cout << endl;
}

如果需要频繁在中间插入和删除元素,那选择 vector 就会影响效率了。

4vector是否为空

在判断容器是否为空的时候,使用empty()来代替size()是否为了0的检查方式,因为empty更加高效时间复杂度是常数时间的,size()时间复杂度不是常数时间的。

原则:使用 empty 判断标准容器是否为空

5vector中的查找

原则:尽量使用标准容器自带的算法代替公共算法。  vector中 没有find函数

但是 vector 中并没有多少自己的算法,倒是 list 中有 remove ,remove_if,sort,reverse 等算法。



注意对于 vector,任何插入删除操作都会引起迭代器失效。所以要小心  即 在循环中 如果删除了某个东西 那么这时候迭代器地址也变了 就指的不对了


上面那句话 是极为重要的 也是最容易犯的错误

参考:http://www.cnblogs.com/caoshenghe/archive/2010/01/31/1660399.html


函数

表述

c.assign(beg,end)

c.assign(n,elem)

[beg; end)区间中的数据赋值给c。

将n个elem的拷贝赋值给c。

c.at(idx)

传回索引idx所指的数据,如果idx越界,抛出out_of_range

c.back()

传回最后一个数据,不检查这个数据是否存在。

c.begin()

传回迭代器重的可一个数据。

c.capacity()

返回容器中数据个数。

c.clear()

移除容器中所有数据。

c.empty()

判断容器是否为空。

c.end()

指向迭代器中的最后一个数据地址。

c.erase(pos)

c.erase(beg,end)

删除pos位置的数据,传回下一个数据的位置。

删除[beg,end)区间的数据,传回下一个数据的位置

c.front()

传回地一个数据。

get_allocator

使用构造函数返回一个拷贝。

c.insert(pos,elem)

c.insert(pos,n,elem)

c.insert(pos,beg,end)

pos位置插入一个elem拷贝,传回新数据位置。

pos位置插入n个elem数据。无返回值。

pos位置插入在[beg,end)区间的数据。无返回值。

c.max_size()

返回容器中最大数据的数量。

c.pop_back()

删除最后一个数据。

c.push_back(elem)

在尾部加入一个数据。

c.rbegin()

传回一个逆向队列的第一个数据。

c.rend()

传回一个逆向队列的最后一个数据的下一个位置。

c.resize(num)

重新指定队列的长度。

c.reserve()

保留适当的容量。

c.size()

返回容器中实际数据的个数。

c1.swap(c2)

swap(c1,c2)

c1c2元素互换。

同上操作。

vector<Elem> c

vector <Elem> c1(c2)

vector <Elem> c(n)

vector <Elem> c(n, elem)

vector <Elem> c(beg,end)

c.~ vector <Elem>()

创建一个空的vector

复制一个vector

创建一个vector,含有n个数据,数据均已缺省构造产生

创建一个含有n个elem拷贝的vector

创建一个以[beg;end)区间的vector

销毁所有数据,释放内存。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值