
前言
要我说c++和c在算法竞赛上有什么最明显的区别,我第一个想到的就是stl了,当你还在手写链表队列的时候,c++一个stl直接就可以写出来阿,我第一次看到大佬们用stl想不嫉妒都难,所以今天来系统的写一下stl,首先,我先来总结一下stl中的容器。因为本人时间较为琐碎,一下写完所有的容器不太现实,所以分开来写。
ps:因为本人的水平也十分有限,所以本系列文章以stl的入门为主,如果有纰漏欢迎大家指出~
vector
众所周知,c语言中数组是要有固定长度的,在我们开一个数组的时候,他的长度也就被固定下来了,而在stl中存在一个“动态数组”,你往vector中存多少数据,他的大小就是多少。
vector 的 size() 是当前元素个数,capacity() 是不重新分配内存时能容纳的元素个数。当一次插入会使元素个数超过容量时,需要重新分配存储空间。具体扩容倍数由实现决定,C++ 标准并没有规定必须翻倍;尾部插入的复杂度保证是摊还常数时间。
下面来看关于vector的使用方法
1 |
|
代码中vector<int>::iterator it;定义的it为迭代器,可以理解为stl容器中的指针,当然这个形容不是很贴切,只是为了便于理解,具体关于迭代器和指针的一些区别我就先不总结了。
当然遍历vector容器也可以用下标访问。
在c++11中,我们可以用auto关键字来定义一个迭代器,如下:
1 |
|
关于vector,还有很多其他使用方法
vec.begin() 返回vector中的首迭代器(指向第一个元素)。
vec.end() 返回vector中的尾迭代器(指向最后一个元素的下一个节点)。
vec.push_back() 在vector的末尾加入一个元素。
vec.pop_back() 在vector的末尾删去一个元素。
vec.empty() 验证vector是否为空,若为空返回1,不为空返回0。
vec.size() 返回vector长度(元素个数)。
vec.capacity() 返回vector的容量(不一定与vec.size()相等)。
vec.swap(b) 将vec和b中的元素进行交换。
vec.clear() 清空vector。
vec.resize(a,b) 指定容器的长度为a,若容器变长,则以b(若无b,则填入0)填充新位置,如果容器变短,则末尾超过容器长度的元素被删除。
vec.reserve(a) 当 a 大于当前容量时,将容量增加到至少 a;否则容量不变。它不会改变 size(),预留的存储空间还不是已构造的元素,不能通过下标访问。后续插入只有在新大小将超过当前容量时,才需要重新分配内存。
vec.max_size() vector所能容纳的最大元素数目,是由系统或者库来限制的,实际上,容器不一定能达到该大小。
对于一个新定义的vector,我们可以先预估一个合理的容量,通过reserve()进行预留,这样可以减少vector在动态扩展容量时的扩展次数,提高。
vec.insert() 插入一个元素。不同使用方法如下:
1 |
|
1 |
|
1 |
|
erase(it) 删除 vector 容器中 it 迭代器指定位置处的元素,并且返回指向被删除元素下一个位置元素的迭代器。该容器的大小(size)会减 1,但容量(capacity)不会发生改变。
例如:
1 |
|
注意:insert和erase都有可能导致迭代器失效
迭代器失效大概有两种情况,我简单介绍一下,
1.迭代器所指向的元素意义改变
2.迭代器“越界操作”,指向了未知的区域。
篇幅原因,我准备在之后的文章中再详细介绍迭代器,这里大家可以先简单了解以下。
vec.emplace() C++ 11 标准新增加的成员函数,用于在 vector 容器指定位置之前构造并插入一个新元素。它将参数转发给元素的构造函数,可能省去临时对象的构造或移动,但不保证总比 insert 或 push_back 更快;在中间插入仍可能移动后续元素,扩容时仍可能重新分配内存。
vector 没有 emplace_front() 成员函数。在头部构造元素可使用 vec.emplace(vec.begin(), 参数...),但这不是常数时间的头部插入。
vec.emplace_back() : 在容器的尾部创建元素。
emplace在其他一些stl容器也有所应用
能在vector使用的其他常用算法(algorithm)
1.sort
sort(vec.begin(),vec.end()) 对vec整体从小到大排列
注意:排序的范围包括括号内第一项,而不包括括号内第二项
2.find
find(vec.begin(),vec.end(),1) 在vec整体范围中,查找元素1,并返回他所在位置。
find函数同上,范围不包括括号内第二项
3.reverse
reverse(vec.begin(),vec.end()) 在vec整体范围中,倒置元素。如1,3,2 reserve 后变为2,3,1。
同上qwq,范围不包括括号内第二项
完~
一些无聊的后话
这篇虽然篇幅不长但是我还是来回整理了好几天,主要是这几天真的忙死了,没什么时间来写,每次忙完别的事再回来写都忘了上次写到哪里了hhhh,所以断断续续在今天总算写完了,如果喜欢的话就给个点赞或者评论关注一下吧(虽然我很菜写不出什么高端东西来,这段时间还是比较忙,如果有时间的话还会来继续把stl容器写完的,毕竟stl这么有意思的东西,不好好整理学习一下怎么行呢。好了,感谢您的阅读,祝您生活愉快~
qwq~
校订记录(2026-10-09):本页从原文迁入后,校正了扩容、reserve 与 emplace 的说明;原始示例代码和原文日期保留。参考:C++ 标准工作草案的 vector 接口、容量规则与插入操作。
评论
评论
留言服务尚未连接。
正在打开留言簿……