学科分类
目录
C++基础

vector类模板

vector是STL中一种自定义数据类型,包含在头文件<vector>中,其定义如下所示:

template<class T, class Allocator = allocator<T>>
class vector;

vector是将元素置于一个动态数组中加以管理的容器,是最简单的序列式容器。它支持随机存取元素。在程序开发过程中,使用vector作为动态数组是非常方便的,尤其是在末端添加或删除元素时,速度非常快。接下来我们就vector创建对象、插入删除元素等基本操作进行详细讲解。

1、创建vector对象

vector模板中定义了不同的重载构造函数,因此vector对象的创建与初始化也有不同的方式。vector创建对象的方式主要有四种。

(1)指定容器大小

vector<元素类型> 对象名(容器大小);

<>中的类型名表示容器中元素的类型,如int就表示此容器中存储的是int类型的数据。注意vector对象在定义后所有元素都会被初始化,如果是基本数据类型,则都会被初始化为0,如果是其他类型容器,则由类的默认构造函数初始化。其示例代码如下所示:

vector<int> v1(10); //创建一个容量大小为10的int类型容器v1
vector<string> v2(5); //创建一个容量为5的string类型容器v2

这种情况下,指定了容器大小,没有指定初始值,标准库就会自动创建一个初始值赋值给数组中的所有元素,这个初始值根据元素类型而定。

(2)指定初始值

还可以用vector对象的大小和统一初始值来定义容器。其格式如下所示:

vector<元素类型> 对象名(容器大小,元素初始值);

示例代码如下所示。

vector<int> v1(10, 1); // 10个元素的初始值都为1
vector<string> v3(3, "aa"); //3个元素的初始值都是”aa”

(3)列表初始化(C++11**新标准)**

C++11新标准还提供了另外一种vector对象初始化的方式,用值的列表来初始化,具体示例代码如下所示:

vector<int> v1{1, 2}; //v1有两个元素12
vector<string> v2 = { "a", "b", "c" }; //v2有三个元素,分别是字符串"a","b","c"

列表初始化有这两种方式,带“=”符号与不带“=”符号均可。

(4)初始化状态为空

vector对象可以初始化状态为空,不指定大小也不指定初始值,示例代码如下所示:

vector<int> v1; //创建一个空的int型对象

v1就是一个初始状态为空的容器。不仅如此,vector对象还可以用来初始化另一个容器对象,代码如下所示:

vector<int> v1(10, 1);
vector<int> v2(v1); //用v1来初始化v2 
vector<int> v3 = v2; //用v2数组给v3数组赋值

注意:用一个vector对象初始化另一个或相互赋值时,两个vector对象的元素类型必须相同。其实它调用的是vector的复制构造函数。

访问vector对象的元素也是用下标的形式,但需要指出的是,空的vector容器不可以用下标直接赋值,例如vector<int> v; v[2] = 2;这是错误的语句,因为此时v是空的,不包含任何元素,所以不能通过下标形式来给元素赋值。

2、获取容器容量和大小

通过8.2.1小节的学习,我们知道,向量容器的容量与容器大小并不一定相同,vector提供了两个函数capacity()和size(),分别获取容器容量和容器大小,其调用形式如下所示:

v.capacity();
v.size();

v是创建的向量对象,如无特殊说明,后续讲解的vector容器的函数调用,其中v均指向量容器。这两个函数分别返回容器的容量和大小。一般情况下向量容器的容量与容器大小都是相同的,但当有元素被删除时,其大小会发生变化。

3、赋值函数

容器中的元素可以在创建对象时赋值,也可以调用vector的成员函数assign()来赋值,assign()用于给容器赋值,其调用形式如下所示:

v.assign(n, elem);  //将n个elem元素赋值给容器
v.assign(begin, end); //将[begin, end)区间中的元素赋值给容器

assign()函数的两种形式都可以给容器赋值,第一种形式的赋值给元素赋同样的数据值,其意义不大;第二种形式是以区间给元素赋值,注意区间是左闭右开,即第一个区间值可以使用,最后一个区间值不可以使用。

4、访问容器中的元素

在学习vector对象的创建时,讲解过访问容器中的元素可以使用下标法,因为vector中重载了[]运算符,除此之外,vector还提供了一个at()成员函数,用来随机访问容器中的元素,其调用如下所示:

v.at(int idx);

该函数返回索引指向的数据,用法和[]运算符相同。

5、从尾部插入和删除元素

vector提供了一对函数push_back()与pop_back()函数,分别用于从末尾向容器添加元素和移除末尾的元素,其调用如下所示:

v.push_back(type elem& t);
v.pop_back(); 

push_back()函数是向vector容器末尾添加元素。先创建一个空的vector对象,再调用push_back()函数向其中添加元素。而pop_back()用于弹出vector容器末尾的一个元素。两个函数的具体用法如例1所示。

例1

 1    #include <iostream>
 2    #include <vector>
 3    using namespace std;
 4    int main()
 5    {
 6        vector<int> v; //创建一个空的vector对象
 7        for (int i = 0; i < 10; i++)
 8            v.push_back(i + 1);  //将元素添加到v中
 9        for (int i = 0; i < 10; i++)
 10            cout << v[i] << "  ";  //输出元素
 11        cout << endl;
 12        v.pop_back();  //移除末尾的元素
 13        for (int i = 0; i < 9; i++) //此时元素个数为9
 14            cout << v[i] << "  ";  //输出元素
 15        cout << endl;
 16        system("pause");
 17        return 0;
 18    }

运行结果如图1所示。

图1 例1运行结果

在例1中,创建了一个空的vector容器v,然后调用push_back()函数向容器尾部添加元素,由图1可知,添加10个元素均成功。接着调用pop_back()函数移除了末尾的元素10,由图1的运行结果可知,末尾元素10移除成功。

C++标准要求vector应该能在运行时高效快速地添加元素。既然vector对象能高效的增长,那么在定义时就没必要指定大小,事实上如果这么做,性能可能更差,只有一种例外情况,就是所有元素的值都一样。一旦元素的值有所不同,最好的方法就是先定义一个空的vector对象,再在运行时向其中添加元素。

6、获取头部和尾部元素

vector提供的front()函数与back()函数分别返回容器的头尾元素的引用,函数调用如下所示:

v.front();
v.back();

这两个函数在获取容器的首尾元素时返回元素的引用。除了这一对函数,vector还提供了begin()与end()函数,这一对函数返回的是头尾元素的迭代器(可以理解为指针)。这两个函数的调用如下所示:

v.begin();
v.end();

begin()返回第一个元素的迭代器,end()返回最后一个元素之后的迭代器。

7、插入和删除元素

vector提供了一对向容器中随机插入和删除元素的函数insert()与erase()函数,其中insert()函数用于向容器中插入元素,它有三种实现形式,如下所示:

v.insert(pos, elem); //在pos位置上插入元素elem,返回新数据的位置
v.insert(pos, n, elem): //在pos位置上插入n个elem元素,无返回值
v.insert(pos, begin, end); //在pos位置插入[begin, end)区间的数据,无返回值

erase()函数用于移除容器中的元素,它有两种形式,如下所示:

v.erase(pos); //移除pos位置上的元素,返回下一个数据的位置
v.erase(begin, end); //移除[begin, end)区间的数据,返回下一个元素的位置

接下来通过一个案例来演示这两个函数的用法,具体如例2所示。

例2

 1    #include <iostream>
 2    #include <vector>
 3    using namespace std;
 4    int main()
 5    {
 6        vector<char> v;  //创建空的vector对象v
 7        v.insert(v.begin(), 'a');  //在头部位置插入元素
 8        v.insert(v.begin(), 'b');
 9        v.insert(v.begin(), 'c');
 10        v.insert(v.begin() + 1, 5, 't');  //在begin()+1位置插入5个t元素
 11        for (int i = 0; i < 8; i++)  //输出元素
 12            cout << v[i] << " ";
 13        cout << endl;
 14        cout << "erase elems:\n"; 
 15        v.erase(v.begin() + 1, v.begin() + 6);//删除begin()+1到begin()+6区间的5个元素
 16        for (int i = 0; i <3; i++)
 17            cout << v[i] << " ";
 18        cout << endl;
 19        system("pause");
 20        return 0;
 21    }

运行结果如图2所示。

图2 例2运行结果

在例2中,创建了一个空的vector容器,代码7-10行调用insert()函数向容器中插入单个元素,第10行调用insert()函数在v.begin()+1位置连续插入5个’t’元素,输出v中的元素如图8-7所示。代码第15行又调用erase()函数删除了v.begin()+1到v.begin()+6之间的5个元素(t元素),然后输出结果只剩下c,b,a三个元素,如图8-7所示。

注意:insert()函数与erase()函数中的位置只能由begin()或end()返回的迭代器来指示,而不能用纯粹的数字作为参数。

点击此处
隐藏目录