Life of xhu

About

C++标准库vector容器学习笔记

Feb 10, 2014

  |   #C++   |   #STL

首先引用《C++标准程序库》中的一句话:

任何地点只要你需要一个动态数组,你就可以使用vector。

像我这种在学了C/C++的基本语法之后又去看了脚本语言的人,有一个非常不习惯的地方就是动态数组,所以在这几天写C++代码的时候,在使用数组时,总是需要使用一个额外的变量来表示正在操作的数组的角标,这几天在网上看大神的C++代码时,看到了一个非常有意思的数据结构,即vector,意思是矢量,但是在C++内部标准库中,这种数据结构承担着扮演者动态数组的角色。

这个数据结构存在于std命名空间下,声明一个vector并进行赋值操作:

#include <iostream>
#include <vector>
using namesapce std;

//创建一个大小为50个int大小的vector
vector<int> v(50);    //如果不声明std命名空间,应使用std::vector<int> v(50)  

//赋值
v.assign(5, 60);     //用60给v中前5个元素复制
v.at(0) = 1;     //第一个元素赋值为1
v[1] = 2;     //第二个元素赋值为2
cout << v.at(0) << v[1] << endl;     //=> 12,最好使用at操作,这个操作会进行越界检查并抛出out_of_range异常,而第二种只会输出相应元素类型的初始值

虽然vector可以看做一个动态数组,但是最好对其使用内存大小也作定义,除了上面一段代码中使用的方法外,关于操作vector的大小还有有两个函数;

  • reserve(n): 声明保留一定大小的空间,但是这些空间必须进行初始化,即push_back(n)/assign()/insert()操作之后才可以使用,如果直接使用at()/[]=操作,将会抛出异常。
  • resize(n): 和上面一段代码中的作用一样,声明之后的空间可以立即进行操作。

vector也有自己的迭代器的,迭代器应该这样声明:

#include <iterator>

vector<int>::iterator pos1 = v2.begin();
vector<int>::iterator pos2 = v2.end();

当然,vector也提供了一些常用的函数:

  • size():返回元素个数,而不是空间大小;
  • empty():判断元素个数是否为0,而不是判断空间大小是否为0;

(上面两个函数返回的值会随着resize()改变,而不会随着reserve()改变,这里我们可以看出,使用resize()可以看作一个reserve()+一次遍历初始赋值操作)

  • assign(v.begin(), v.end()):用另一个数据结构里的一个系列的值给这个vector赋值,这里的begin()/end()都是相应数据结构里的迭代器;

  • assign(n, val):将vector里的头n个元素赋值为val

  • insert(pos, val)/insert(pos, n, val):在迭代器指向的位置上插入一个/n个值为val的元素;

  • begin()/end():迭代器,在insert()等使用迭代器的地方可以使用,并且可以使用+/-操作改变位置,如以下代码:

    vector<int> v2(50);
    v2.insert(v2.begin(), 1);
    v2.insert(v2.begin() + 1, 2);
    cout << v2.at(0) << "  " << v2.at(1) << endl;     //=> 1  2  
    
  • front()/back():返回vector的第一个/最后一个元素;

  • push_back(elem)/pop_back():向vector的最后加入一个元素/从尾部删除一个元素;(我去,以后还写栈干屁啊,直接用vector就好了...)

  • clear():移除所有元素,将vector容器清空;

  • erase(pos)/erase(beg, end):前者是将一个位置(迭代器)上的元素删除,后者则是两个迭代器间的元素,比如:

    v2.erase(5);     //删除第四个元素
    v2.erase(v2.begin(), v2.begin() + 3);    //删除从开始到第四个元素
    
  • 全局函数remove(pos1, pos2, val)/find(pos1, pos2, val)remove()将两个迭代器中间和val相等的都删除,find则返回一个指向两个迭代器之间第一个值为val的元素所在的位置,返回值也是一个迭代器:

    vector<int>::iterator pos = find(v2.begin(), v2.end(), 2);
    v2.erase(pos);
    

erase()remove()的不同之处在于,erase()会使vectorsize减小,而remove()size无影响。

insert()会改变vectorsize大小,插入一次size就会+1,而如果使用assign(n, val)函数,则会将vectorsize变为n