C++ STL vector使用总结

vector是C++标准模板库中的部分内容,中文偶尔译作“容器”。它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。使用时需要包含头文件<vector>。

1.vector初始化

1.1vector初始化主要有三种方法。

(1)vector <type> a;    不初始化容器(本文就容器和数组不加区别)大小,即创建一个空容器,之后可以通过push_back向容器后放入元素。

(2)vector <type> a(10);    初始化容器大小(size)为10,如果是int、float等类型,默认初始化值为0,char类型默认初始化值为一个空格,string类型没有初始化值(即使为空容器大小还是为10)。

vector<int> a(10,1);    初始化容器大小为10,值都为1。

(3)vector<int> a={3,4,5,6};    将容器初始化为{3,4,5,6}。

注意:

(1)必须经过初始化的空间才能够进行赋值,比如

vector <int> a;
a[1]=1;

这是不对的,也是初学者最容易犯的一个错误,这时的a并没有初始化任何空间,a的大小和容量都为0,a[1]这个位置并不存在,自然也就不能给a[1]赋值。不过可以通过push_back向后插入元素,对应容器大小自动加1。

(2)使用vector <int> a(10)初始化后,容易前10个元素会有默认初始值0,此时再通过push_back插入元素将会在a[10]位置(第11个)。

1.2多维数组的创建

前面说到,vector是一个能够存放任意类型的动态数组,既然是任意类型,自然也包括vector本身。

(1)给所有维度初始化空间

vector<vector<int>>v(5, vector<int>(6));//初始化一个二维数组,5行6列,值全为0

也可以看作v这个容器里装有5个vector容器,这5个vector里面每个装有6个int数据,且这样初始化值全为0。

cout << v.size() << endl;//输出为5
cout << v[0].size() << endl;//输出为6
cout << v[0][0] << endl;//输出为0

 (2)只给一个维度初始化空间

vector<vector<int>>v(5);//初始化一个二维数组,5行,每行列数不确定

由于列数为初始化空间,相当于v这个容器里面装了5个vector,每个vector里装的元素不确定,因此不能使用v[0][0]=1这种方式赋值,可以通过v[i].push_back()来向第i个容器(i从0开始)放入数据(即向第i行放入数据)。

由于数组行数已经初始化大小,因此v[i]可直接赋值,即可以通过v[i]=v2(v2为另一个vector<int>类型容器)来给v的第i个元素(此处元素为vector<int>类型)赋值。

(3)所有维度都未初始化大小

vector<vector<int>>v;//初始化一个二维数组,行列都不确定

也可以看着一个容器v,里面存放vector<int>类型元素,存放个数未知,vector<int>类型元素里面包含的int数据个数也未知。因此既不能使用v[0][0]=1这种方式赋值,也不能使用v[i]=v2(v2为另一个vector<int>类型容器)来给v的第i个元素(此处元素为vector<int>类型)赋值。

只能v.push_back(vi),vi为vector<int>类型容器。

1.3vector元素的访问

(1)通过迭代器访问

for (vector<int>::iterator it = a.begin();it != a.end(); ++it) 
{
    cout << *it << ' ';
}

 (2)通过下标访问

for(int i=0;i<a.size();++i)
{
    cout<<a[i]<<" ";
}

 (3)把迭代器当作指针

for (int i = 0; i < v2.size(); i++)
{
	cout << *(v2.begin() + 1) << " ";
}

2.vector对象的一些重要操作

(1)a.assign(2,3);//给a分配2个元素,值为3,相对于重新初始化。不过如果原来a.capacity()大于2,重新分配之后容量不会减小。
(2)a.assign(b.begin(),b.begin()+2);//把b中前2个值分配给a,不包括b.begin()+2。其中b.begin()可以是其他类型数组的指针
(3)a.back();//返回a的最后一个元素,不存在则报错
(4)a.front();//返回a的第一个元素,不存在则报错
(5)a[i]; //返回a的第i个元素,当且仅当a[i]存在
(6)a.clear();//清空a中的元素,size变为0,capacity不会减小
(7)a.empty();//判断a是否为空,空则返回ture,不空则返回false
(8)a.pop_back();//删除a向量的最后一个元素
(9)a.erase(a.begin()+1,a.begin()+3);
//删除a中第1个(从第0个算起)到第2个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)
(10)a.push_back(5);//在a的最后一个向量后插入一个元素,其值为5
(11)a.insert(a.begin()+1,5);//在a的第1个元素(从第0个算起)的位置插入数值5,
        //如a为1,2,3,4,插入元素后为1,5,2,3,4
(12)a.insert(a.begin()+1,3,5);//在a的第1个元素(从第0个算起)的位置插入3个数,其值都为5
(13)a.insert(a.begin()+1,b+3,b+6);//b为数组,在a的第1个元素(从第0个算起)的位置插入b的第3个元
//素到第5个元素(不包括b+6),如b为1,2,3,4,5,9,8,插入元素后为1,4,5,9,2,3,4,5,9,8
(14)a.size();//返回a中元素的个数;
(15)a.capacity();//返回a在内存中总共可以容纳的元素个数
(16)a.rezize(10);//将a的现有元素个数调至10个,多则删,少则补,其值随机,不会减小a.capacity()
(17)a.rezize(10,2);//将a的现有元素个数调至10个,多则删,少则补,其值为2
(18)a.reserve(100);//将a的容量(capacity)扩充至100,可以避免内存多次容量扩充操作
        //(当a的容量不足时电脑会自动扩容,当然这必然降低性能)
(19)a.swap(b);//b为向量,将a中的元素和b中的元素进行整体性交换(包括容量capacity)
(20)a==b; //b为向量,向量的比较操作还有!=,>=,<=,>,<({2,3,0}>{2,3})

3.常用算法

STL主要分为容器、迭代器、算法三个部分,迭代器是容器和算法沟通的桥梁。迭代器和指针很相似,a.begin()指向a中第一个元素,a.end()指向a中最后一个元素后面一个位置。

使用时需要包含头文件<algorithm>

(1)sort(a.begin(),a.end()); //对a中的从a.begin()(包括它)到a.end()(不包括它)的元素进行从小到大排列

如果想从大到小排序,可定义比较函数:

bool flag(const int &a, const int &b)
{
	return a > b;
}

排序时调用:sort(a.begin(),a.end(),flag);即可。

当然也可以先从小到大排序,之后再反转容器。

(2)reverse(a.begin(),a.end()); 
//对a中的从a.begin()(包括它)到a.end()(不包括它)的元素倒置,但不排列,如a中元素为1,3,2,4,倒置后为4,2,3,1
(3)find(a.begin(),a.end(),10); 
//在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置

4.注意事项

4.1.4.capacity

使用a.assign;a=b;a={1,2,3}等方式重新赋值后a.size()会变成复制后的容器大小,a.capacity()不会减小。

例如:

vector<int> a(10);
a={1,2,3};//此时a.size()变为3,a.capacity()仍为10

vector的内存占用空间只增不减,比如你首先分配了10,000个字节,然后erase掉后面9,999个,留下一个有效元素,但是内存占

用仍为10,000个。所有内存空间是在vector析构时候才能被系统回收。

析构函数~vector()

销毁容器对象并回收了所有分配的内存

4.2.a.size()返回值为无符号整型

vector<int>num = {};
int i = num.size() - 1;

cout << i << endl;//将其转换为int型数据输出
cout << num.size() - 1 << endl;//不将其转换为int型数据输出

输出为: 

当a.size()为0时,a.size()-1将会变成一个很大的数,如果运行下面这段代码:

for(int i=0;i<vector.size()-1;i++)

将会变成死循环。想要解决只需强制转换其类型即可。

4.3迭代器和指针

迭代器和指针有很大程度的相似度,迭代器就是STL容器的专属指针。

比如可以通过*a.begin()输出a[0]的值,但是a.begin()不是a[0]的地址,且a.begin()无法输出,想输出a[0]地址还是得cout<<&a[0]。

vector使用的算法大部分也可用于普通数组(重载),比如sort也可用于普通数组排序,这时输入变为指针:

int a[5] = { 2,4,1,4,6 };
sort(a, a + 5);
for (int i = 0; i < 5; i++)
{
	cout << a[i] << " ";
}
发布了33 篇原创文章 · 获赞 148 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_40692109/article/details/104202498
今日推荐