• vector容器(一)


    一、 Vector简要描述

    vector是C++标准模版库STL提出的一种顺序存储结构,之所以称之为“容器”,是因为vector是一个模板类,它允许我们重复利用已有的实现构造自己的特定类型下的数据结构。通过设置vector的参数允许我们制定容器汇总的元素的数据类型,可以将许多重复而乏味的工作简化。

    众所周知,常用的数据结构有array(数组)、list(链表)、tree(树)、stack(栈)、heap(堆)、queue(队列)、hash table(散列表)、set(集合)、map(映射表)等。 --摘自《STL源码剖析》by 侯捷

    根据在容器中的排列特性,这些数据结构分为序列式容器(sequence container)和关联式容器(associative container)。   

    序列式容器: 关联式容器:
    Array: C++的内建数据结构   RB-tree(Red-Black Tree,红黑树)
    heap: 通过算法的方式实现(大顶堆/小顶堆) map/mulitmap: 内部实现方式,RB-Tree
    priority-queue: 本质还是heap,通过算法的方式实现 set/multiset: 内部实现方式,RB-Tree
    list/slist:链表  [hash table]: 非标准
    deque: 双向链表

     [hash_multiset]: 非标准

     [hash_mutimap]:非标准

    stack/queue: 适配器,底层由deque实现

     [hash_set]:  非标准

     [hash_map]: 非标准

    需要指出的是:

    1. vector在内存中是顺序存储的,其满足顺序数据结构的特征:支持顺序访问和随机访问。

    2. 在C++程序中,如果没有特殊说明或者特殊要求的话,当需要使用动态数组时,请尽量使用vector,避免用户自己定义动态数组。理由如下:

       (1) vector虽然本质上的实现方式还是动态数组,但是作为STL一员,vector提供了许多封装好的函数,并且其内部实现经过了大量的测试与优化,使得用户使用更为方便。

       (2) vector就C++用户自定义的动态数组在元素的动态插入和删除方面,提供了较为方便的库函数,避免用户在指针使用上出现不必要的错误。

    3. 虽然vector提供了元素的动态插入和删除操作,但是当程需要频繁的插入和删除操作的时候,vector就不适用了,而应该使用deque或者list。

    二、Vector用法 

    1. vector容器的定义:(参考自:http://www.cplusplus.com/reference/vector/vector/

    在C++98标准中,vector的声明如下:

    1 template < class T, class Alloc = allocator<T> > class vector; // generic template

    由于vector是STL的一员,所以在程序中需要定义vector时,需要引用命名空间std:

    using namespace std; 

    在程序中定义一个某一特定类型的vector的方式如下:

    vector<Data_Type> vi; // vi为vector的变量名, Data_Type为vi中元素的类型

    2. vector类中成员变量

       具体的成员变量如下:

    member type

    definition

    notes

    value_type

    The first template parameter (T)

     

    allocator_type

    The second template parameter (Alloc)

    defaults to:allocator<value_type>

    reference

    allocator_type::reference

    for the default allocator:value_type&

    const_reference

    allocator_type::const_reference

    for the default allocator: const value_type&

    pointer

    allocator_type::pointer

    for the default allocator:value_type*

    const_pointer

    allocator_type::const_pointer

    for the default allocator: const value_type*

    iterator

    a random access iterator to value_type

    convertible to const_iterator

    const_iterator

    a random access iterator to const value_type

     

    reverse_iterator

    reverse_iterator<iterator>

     

    const_reverse_iterator

    reverse_iterator<const_iterator>

     

    difference_type

    a signed integral type, identical to:iterator_traits<iterator>::difference_type

    usually the same as ptrdiff_t

    size_type

    an unsigned integral type that can represent any non-negative value of difference_type

    usually the same as size_t


     在众多成员变量中,我们经常会用到iterator,这个有很多中叫法:游标,迭代器。
     
    该变量用于对vector中某个位置进行操作。一般用法:
    vector<Data_Type>::iterator iter; // iter为迭代器名,Data_Type为vector中元素的类型

     会破坏迭代器的函数操作,任何插入和删除操作:

    insert , push_back, pop, remove, erase,  assign

    3. vector中常用函数的用法:

    (1)赋值函数 assign

    1 template <class InputIterator>
    2     void assign (InputIterator first, InputIterator last);  //1. 复制    
    3     void assign (size_type n, const value_type& val);    // 2. 填充

    若定义某vector<value_tpye> 对象 vi, 那么vi的成员函数assign,有两种实现方法:

    填充,自vi的头部开始连续的n个元素都填入元素值val。

    复制,将另一个vector或者某种连续存储的区间的某一个区间复制到新的vector vi之中。

    调用实例:

     1 #include<iostream>
     2 #include <vector>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     vector<int> v1;
     8     vector<int> v2;
     9     vector<int> v3;
    10     int from[3] = {1,2,3};
    11     
    12     v1.assign(10,7);  // 填充
    13     cout<<v1.size()<<endl;
    14 
    15     v2.assign(v1.begin().v1.end()); //vector同类型复制     
    16     cout<<v2.size()<<endl;
    17 
    18     v3.assign(from, from+2); //连续内存复制 
    19     cout<<v3.size()<<endl;
    20 
    21     return 0;
    22 } 
    assign使用方法

    (2)访问函数at 

        参考:http://www.cplusplus.com/reference/vector/vector/at/

        对于at的使用,需要注意其返回值为reference,v.at(pos)表示的是在vector中pos所在的位置上的元素。

        ps: at函数是Exception safety的,也就是说当at访问的是一个非法地址的时候,at会throw一个out of range的异常,不会有内存溢出。

       

        与at类似的函数还有:     

    begin: 返回vector首元素的地址

    front: 返回vector第一个元素值

    end: 返回vector尾元素的地址

    back :   返回vector最后一个元素的值


    (3) 插入函数 insert
     

    iterator insert (iterator position, const value_type& val); //单元素定点插入    
    
    void insert (iterator position, size_type n, const value_type& val);    //定点多元素填充插入
    
    template <class InputIterator> 
    void insert (iterator position, InputIterator first, InputIterator last); //定点连续内存覆盖插入

    与assign函数类似,对vector进行插入操作insert的实现也是分为填充和复制,不过多了一个单元素插入的操作,此外就是insert函数规定了插入的位置。

    实现实例:

     1 #include <iostream>
     2 #include <vector>
     3 using namespace std;
     4 
     5 vector<int> vi;
     6 
     7 void print(vector<int> v)
     8 {
     9      vector<int>::iterator iter;
    10      for(iter = v.begin(); iter!= v.end();iter++)
    11      {
    12          cout<<*iter<<" ";
    13      }
    14      cout<<endl;
    15 }
    16 
    17 int main()
    18 {   
    19     vi.clear();    
    20     vector<int>::iterator iter;
    21     iter = vi.begin();
    22     /******************************************************
    23      *  insert(iterator pos,int n,elem_type elem);
    24      *  在pos位置及之后的n-1个位置上插入元素elem 
    25      ******************************************************/
    26     vi.insert(iter,10,20);
    27     print(vi);
    28 
    29     vi.clear();  //清空vector   
    30     for(int i=0;i<10;i++)
    31       vi.push_back(i);
    32     print(vi);
    33     
    34     vi.clear();
    35     iter = vi.begin();
    36     /******************************************************
    37      *  insert(iterator pos,elem_type elem);
    38      *  在pos位置上插入元素elem 
    39      ******************************************************/
    40     for(int j=0;j<10;j++)
    41         vi.insert(iter+j,j);
    42         
    43     /******************************************************
    44      *  insert(iterator pos, iterator begin, iterator end);
    45      *  将vi中的[begin,end]之间的数据在pos位置上插入 
    46      ******************************************************/
    47     vi.insert(iter, vi.begin(), vi.end());
    48     print(vi);
    49     return 0;
    50 }
    insert实现

    与insert类似的函数还有:

             push_back(value_type & value); 只能在vector的末尾加入value.

    (4)删除函数erase

    iterator erase (iterator position); //删除单个元素
    iterator erase (iterator first, iterator last); //删除连续区间内的元素

    由于删除某一个元素之后迭代器会失效,所以需要特别注意连续删除的时候迭代器计数问题。

     1 #include <iostream>
     2 #include <vector>
     3 using namespace std;
     4 
     5 int main ()
     6 {
     7   vector<int> myvector;
     8 
     9   // 赋值操作
    10   for (int i=1; i<=10; i++) myvector.push_back(i);
    11 
    12   // 删除第6个元素
    13   myvector.erase (myvector.begin()+5);
    14 
    15   // 删除连续的3个元素
    16   myvector.erase (myvector.begin(),myvector.begin()+3);
    17 
    18   cout << "myvector contains:";
    19   for (unsigned i=0; i<myvector.size(); ++i)
    20        cout << ' ' << myvector[i];
    21   cout << '
    ';
    22 
    23   return 0;
    24 }
    erase使用

    类似函数: clear:清空vector中的元素

    (5) 容量函数 size

    在vector中与容量有关的函数有:

    capacity

    返回系统当前为vector分配的内存大小

    size

    返回当前vector中元素的个数

    max_size

    返回系统能够为vector分配的最大内存的大小

    resize(int rsize,value_type elem)

    改变当前vector的大小成rsize:

    1)如果rsize大于当前vector的大小n,则将[n,rsize-1]区间内填充elem

        elem 默认值为0

    2)如果resize小于当前vector大小n,则将当前的vector截取rsize大小


    resize使用方法resize实现:

    参考:http://www.cplusplus.com/reference/vector/

    转载请指明出处http://www.cnblogs.com/double-win/,谢谢~

  • 相关阅读:
    到底有多少种智能指针(smart pointer)
    QSettings提供了非常方便的注册表读写
    阿里腾讯亿元级投资版图:阿里爱买超市,腾讯娱乐至上(恐怖)
    gcc安装教程(学习Linux编程只需安装cygwin)
    苹果抛弃的芯片公司Imagination被中资49亿溢价收购
    NET Core2
    HelloWorld RabbitMQ
    redis 集群
    kafka
    Impala简介PB级大数据实时查询分析引擎
  • 原文地址:https://www.cnblogs.com/double-win/p/3642887.html
Copyright © 2020-2023  润新知