标准库类型vector表示对象的集合,其中所有对象的类型都相同。集合中每个对象都有一个与之对应的索引,索引用于访问对象。源于vector 包含着其他对象,所以它常被称作容器。
C++中含有类模板和函数模板,其中vector是一个类模板。编译器根据模板创建类或函数的过程称为实例化。
定义和初始化vector对象
#include<iostream>
#include<vector>
using namespace std;
void show(vector<int>& vec)
{
vector<int>::iterator it = vec.begin();
for (; it != vec.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
/**************定义和初始化vector对象*******************/
vector<int> vec1; //vec是一个空vector,它潜在的元素类型是int类型,执行默认初始化
show(vec1); //无值打印
vec1.push_back(1);
vec1.push_back(2);
show(vec1); //1 2打印
vector<int> vec2(vec1); //vec中包含有v1 所有元素的副本(有点像调用vector<int>的拷贝构造函数)
show(vec2);
vector<int> vec3=vec1; //等价于vec2(v1),vec2 中包含有v1所有元素的副本(有点像调用vector<int>的赋值函数)
show(vec3);
vector<int> vec4(3, 10); //vec3包含了3个重复的元素,每个元素的值都是10
show(vec4); //10 10 10
vector<int> vec5(3); //vec5包含了3个重复的元素,每个元素的值都是0
show(vec5); //0 0 0
vector<int> vec6{9,8,7,6}; // vec6包含了初始值个数的元素,每个元素都被赋予相应的初始值
show(vec6); //9 8 7 6
vector<int> vec7={ 11,12,13 }; // 等价于vec6{a,b,c……}
show(vec7); //11 12 13
return 0;
}
C++11中新标准提供了列表初始化vector对象,即
vector<int> vec={1,2,3}
在此,请注意上述初始化方式是大括号,如果使用小括号,则使用错误。
易错点
vector<int> v1(10);//v1 有10个元素,每个元素值为0
vector<int> v2{10};//v1 有1个元素,元素值为10
vector<int> v1(10,1);//v1 有10个元素,每个元素值为1
vector<int> v2{10,1};//v1 有2个元素,元素值为10和1
vector 的基本操作
int main()
{
vector<int> vec1;
vec1.push_back(1); //向vec1的尾端添加一个值为1的元素
vec1.push_back(2);
show(vec1);
cout << vec1.size() << endl;//输出2 vec1.size()返回vec1中的元素个数
cout << vec1[1] << endl;//输出2 返回vec1中第1个位置上元素的引用
//cout << vec1[3] << endl;//错误 第3个位置失效
if (vec1.empty()) //如果vec1不含有任何元素,返回真;否则返回假
{
cout << "容器是空的" << endl;
}
else
{
cout << "容器非空" << endl;
}
return 0;
}
参照vector 的基本方法使用即可
迭代器
迭代器是用来访问容器中的元素,其中对应类型中的begin成员负责返回指向第一个元素(或第一个字符)的迭代器,对应end成员负责返回指向容器“尾元素的下一个位置”的迭代器。
特殊情况下如果容器为空,则begin和end 返回的是同一个迭代器,都是尾后迭代器。
迭代器运算符
运算符类型 | 说明 |
---|---|
*iter | 返回迭代器iter所指元素的引用 |
iter->mem | 解引用iter并获取该元素的名为mem的成员,等价于(*iter).mem |
++iter | 令iter指向容器中的下一个元素 |
–iter | 令iter指向容器中的上一个元素 |
iter1==iter2 | 判断两个迭代器是否相等,如果两个迭代器指向的是同一个元素或者是同一个容器的尾后迭代器,则相等;反之,不想等 |
iter1!=iter2 | 判断两个迭代器是否相等,如果两个迭代器指向的是同一个元素或者是同一个容器的尾后迭代器,则相等;反之,不想等 |
迭代器的使用
int main()
{
vector<int> vec1;
vec1.push_back(1); //向vec1的尾端添加一个值为1的元素
vec1.push_back(2);
vector<int>::iterator it = vec1.begin();
for (; it!=vec1.end();it++)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
代码实例:
#include<iostream>
#include<vector>
#include<time.h>
#include<functional> //STL函数对象所在头文件
#include<algorithm>
using namespace std;
void show(vector<int>& vec)
{
vector<int>::iterator it = vec.begin();
for (; it != vec.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void dealOne(vector<int>& vec)
{
vector<int>::iterator it = vec.begin();
/*for (; it != vec.end();it++) //错误,数据清除不干净,中间有跳过环节
{
if (*it % 2 == 0)
{
it = vec.erase(it);
}
}*/
for (; it != vec.end();)
{
if (*it % 2 == 0)
{
it = vec.erase(it);
}
else
{
it++;
}
}
cout << endl;
}
int main()
{
vector<int> vec1;
srand((unsigned)time(NULL));
for (int i = 0; i<20; ++i)
{
vec1.push_back(rand() % 100);
}
show(vec1);
dealOne(vec1);
show(vec1);
return 0;
}
上述代码中使用了vector 的earse ()方法,清除某个元素,并返回清除该元素后下一个元素的迭代器。
接着我们在上面代码的基础上再加一层功能,在现在获取的基数前面加0,代码如下:
#include<iostream>
#include<vector>
#include<time.h>
#include<functional> //STL函数对象所在头文件
#include<algorithm>
using namespace std;
void show(vector<int>& vec)
{
vector<int>::iterator it = vec.begin();
for (; it != vec.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void dealOne(vector<int>& vec)
{
vector<int>::iterator it = vec.begin();
/*for (; it != vec.end();it++) //错误,数据清除不干净,中间有跳过环节
{
if (*it % 2 == 0)
{
it = vec.erase(it);
}
}*/
for (; it != vec.end();)
{
if (*it % 2 == 0)
{
it = vec.erase(it);
}
else
{
it++;
}
}
cout << endl;
}
void dealTwo(vector<int>& vec)
{
vector<int>::iterator it = vec.begin();
for (; it != vec.end();++it)
{
if (*it % 2 != 0)
{
it = vec.insert(it,0);
it++;
}
}
cout << endl;
}
int main()
{
vector<int> vec1;
srand((unsigned)time(NULL));
for (int i = 0; i<20; ++i)
{
vec1.push_back(rand() % 100);
}
show(vec1);
dealOne(vec1);
show(vec1);
dealTwo(vec1);
show(vec1);
return 0;
}
其中,有需要考虑迭代器失效的问题。但是,我认为在理解vector 的内存基础上,代码逻辑必须是正确的,否则就不是迭代器失效的问题。在《C++primer》书中第99页提到:但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。那么在上面的代码中,我实际上已经在容器中添加了元素,只是让该容器的迭代器实时更新,就可以了。