向量 vector
vector 是STL中最常用的容器,其特点是占用连续内存空间,对数据的随机访问支持的很好,既可以像数组那样被访问元素的下标来访问,也可以使用其提供的成员函数来at()来访问。向量是一个按照尾部开口设计的容器,因此在其尾部进行数据的输入和输出效率最高。向量定义于头文件 vector,命名于名字空间 std。
1. 1 vector 对象的定义和初始化
vector 有多个构造函数,用户可以根据需要在程序中选择,常用的构造函数如下:
构造函数 | 作用 |
vector(); | 创建一个没有任何元素的空向量 |
vector(vector&& _Right); | 创建一个向量并且用向量_Right初始化该向量 |
vector(size_type Count ); | 创建一个大小为Count的向量 |
voctor(size_type _Count,const Type& _val) | 创建一个大小为_Count的向量,该向量所有元素初始化为_val |
template <class InputIterator> vector(InputIterator _First,InputIterator _Last); |
创建一个向量,并以迭代器_First和_Last之间的元素初始化该向量 |
另外,vector重载了运算符operator=,可以以复制的方式在两个vector对象之间复制数据。
范例:测试上表中的构造函数
#include<vector>
#include<iostream>
using namespace std;
int main()
{
vector<int>::iterator v1_Iter,v2_Iter,v3_Iter,v4_Iter,v5_Iter,v6Iter;
//创建一个长度为3初始值为0的int型向量
vector<int>v1(3);
cout<<"v1=";
for(v1_Iter=v1.begin();v1_Iter!=v1.end();v1_Iter++)
cout<<""<<*v1_Iter<<endl;
//创建一个长度为5初始值为2的int型向量
vector<int>v2(5,2);
cout<<"v2=";
for(v2_Iter=v2.begin();v2_Iter!=v2.end();v2_Iter++)
cout<<""<<*v2_Iter<<endl;
//创建一个int型向量并用v2初始化它
vector<int>v3(v2);
cout<<"v3=";
for(v3_Iter=v3.begin();v3_Iter!=v3.end();v3_Iter++)
cout<<""<<*v3_Iter<<endl;
//创建一个int型向量并用v2 的一部分初始化它
vector<int>v4(v2.begin()+1,v2.begin()+3);
cout<<"v4=";
for(v4_Iter=v4.begin();v4_Iter!=v4.end();v4_Iter++)
cout<<""<<*v4_Iter<<endl;
return 0;
}
输出结果如下图:
对于数据的读取,vector主要提供了如下表的成员函数,注意向量中第一个元素的位置为0:
访问表达式 | 说明 |
reference front(); const_referrence front() const; |
返回第一个元素 |
reference back(); const_reference back() const; |
返回最后一个元素 |
下表给出vector提供的删除、插入、等用于改变元素只能的成员函数。成员函数后加const的意思是常量成员函数。也就是这个成员函数不会修改该类的任何成员数据。
成员函数 | 说明 |
reference operator[](size_type Pos); const_reference operator[](size_type Pos) const; |
返回由Pos指定位置上的元素 |
reference at(size_type Pos); const_reference at(size_type Pos) const; |
返回由Pos指定位置上的元素 |
clear(); | 从容器中删除所有元素。 |
erase(position); | 删除由position指定的元素 |
erase(beg,end); | 删除从beg到end-1之间所有的元素 |
insert(position,elem); | 将elem的一个拷贝插入由position的位置 |
insert(position,n,elem); | 将elem的n个拷贝插入由position的位置 |
insert(position,beg,end); | 将从beg到end-1的所有元素的拷贝插入position指定位置 |
push_back(elem); | 将elem的一个拷贝插入vector的末尾 |
pop_back(); | 删除最后元素 |
resize(num); | 将元素的个数改为num,如果size()增加,由默认构造函数负责创建这些元素 |
resize(num,elem); | 将元素的个数改为num,如果size()增加,由默认构造函数将这些元素初始化为elem。 |
范例:编写一个程序,在程序中使用一个可以存放整型(int)的vector对象,并在尾部逐次压入103,765,208,435数据,然后再完成以下工作。
(1)分别使用函数at()和下标法在显示器上显示向量内容。
(2)使用下标法为向量中,每一个元素乘以2后会送个数据
(3)使用at(),每一个元素乘以2后会送个数据。
(4)使用迭代器遍历并显示。
(5)使用迭代器定位在向量中第3个数据位置插入88.代码如下:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
//定义存放int的vector
vector<int>intvector;
int i;
//尾部压入4个数
intvector.push_back(103);
intvector.push_back(765);
intvector.push_back(208);
intvector.push_back(435);
//使用下标读取
cout<<"第一行数据:";
for(i=0;i<4;i++)
cout<<intvector[i]<<" ";
cout<<endl;
//使用at读取
cout<<"第二行数据:";
for(i=0;i<4;i++)
cout<<intvector.at(i)<<" ";
cout<<endl;
//使用下标写数据
for(i=0;i<4;i++)
intvector[i]*=2;
cout<<"第三行数据:";
for(i=0;i<4;i++)
cout<<intvector[i]<<" ";
cout<<endl;
//使用at()写数据
for(i=0;i<4;i++)
intvector.at(i)*=2;
cout<<"第四行数据:";
for(i=0;i<4;i++)
cout<<intvector.at(i)<<" ";
cout<<endl;
//定义迭代器
vector<int>::iterator vectorIt;
//使用迭代器读取数据
cout<<"第五行数据:";
for(vectorIt=intvector.begin();vectorIt!=intvector.end();vectorIt++)
cout<<*vectorIt<<" ";
cout<<endl;
//使用迭代器插入数据
vectorIt=intvector.begin();
++vectorIt;
++vectorIt;
intvector.insert(vectorIt,88);
//使用迭代器输出数据
cout<<"第六行数据:";
for(vectorIt=intvector.begin();vectorIt!=intvector.end();vectorIt++)
cout<<*vectorIt<<" ";
cout<<endl;
return 0;
}
运行结果如下:
C++11新增的内容,列表初始化和范围for。
#include<iostream>
#include<vector>
using namespace std;
int main()
{
//创建一个int 向量v1,使用列表初始化
vector<int>v1 = { 1, 6, 4, 9 };
//输出
cout << "v1=";
for (auto i : v1)
cout << " " << i;
cout << endl;
//创建v2
vector<int>v2 = { 78, 89, 40, 9 };
//输出
cout << "v2=";
for (auto i : v2)
cout << " " << i;
cout << endl;
v1 = { 8, 99, 34, 21, 67 };
//输出
cout << "v1=";
for (auto i : v1)
cout << " " << i;
cout << endl;
//
for (auto &i : v1)
i = 2 * i;
for (auto &i : v1)
cout << " " << i;
cout << endl;
return 0;
}
在使用g++进行编译时需要将其设置为支持c++11。