前言
由于本文涉及内容比较多,为了尽可能的讲详细些,会把各种例子附上,所以代码样例会比较多,也为了更好的布局,本系列将分开讲解,并且前期为了更加贴合实战需求,暂时只对一些常用的STL容器和基本功能进行讲解。
为了使每篇文章具有一定的独立性,后续的文章大多数会将之前文章涉及的知识点中提取,并且在后续会将相应的例子补上。
本文STL系列知识参考《C++语言程序涉及(第5版)》
STL指南
- 容器的基本功能与分类
- 顺序容器
- 关联容器
无序容器
无序容器分别是unordered_set
,unordered_map
,unordered_multiset
,unordered_multimap
这些容器并不是使用比较运算符来组织怨怒是的,而是通过一个哈希函数和键类型的==运算符。
无序容器提供了与有序容器相同的操作,如find,insert等
但是由于元素未按照顺序存储,一个使用无序容器的程序的输出(通常)会与使用有序容器的版本不同
默认情况下,无序容器使用键类型==运算符来比较怨怒是,它们还使用一个hash<key_type>类型的对象来生成每个元素的哈希值,C++未内置类型提供了hash模板,还为一些标准库类型,如string等定义了hash。
但是不能直接定义关键字类型为自定义类类型的无需日期,而必须提供我们自己的hash模板版本
基本功能
q1,q2表示不指向s元素的输入迭代器
S表示容器类型名
s表示S的实例
T表示S容器的元素类型
t表示T的实例
K表示S的键类型
k表示K的实例
n表示一个整数
p1,p2表示指向s的迭代器
构造函数
除了使用默认构造函数,也可以使用迭代器区间表示的序列进行构造
1.S s(q1,q2);
将[q1,q2)区间内的数据作为s的元素构造s
单重关联容器
当[q1,q2)范围内出席那相同键的元素时,只有第一个元素会被加入s
多重关联容器
[q1,q2)范围内的所有元素均被无条件加入s
插入元素
插入一个或多个元素
与顺序容器不同的时,无须通过迭代器指定插入位置
1.s.insert(t)
把t插入s中
单重关联容器
只有当不存在相同键的元素时才成功插入,返回pair<S::iterator,bool>
插入成功时,返回被插入元素的迭代器和true,
否则返回与t的键相同的元素的迭代器和false
多重关联容器
2.s.insert(p1,t)
将t插入s中,p1是一个提示的插入位置,如果提示准确(即t的键大小正好在p1前)则可以提高插入效率,及时提示不准确也可以正确完成插入,总是返回一个迭代器
单重关联容器
只有当不存在相同键的元素才可以成功插入
插入成功后,返回被插入元素的迭代器
否则返回与t的键相同的元素的迭代器
3.insert(q1,q2)
相当于按顺序对[q1,q2)区间的每个元素x分别执行s.insert(x)
元素删除
通过erase来删除,顺序容器提供的两种通过迭代器指定删除元素的调用形式对关联容器仍然有效,此外关联容器还允许通过键删除元素
1.s.erase(p1)
删除p1指向的元素
2.s.erase(p1,p2)
删除[p1,p2)区间的元素
3.s.erase(k)
删除所有键为k的元素,返回被删除元素个数
基于键的查找和计数
1.s.find(k)
找到任意一个键为k的元素,返回该元素的迭代器,如果s中没有键为k的元素,返回s.end()
2.s.lower_bound(k)
得到s中第一个键值不小于k的元素的迭代器
3.s.upper_bound(k)
得到s中第一个键值大于k的元素的迭代器
4.s.equal_range(k)
得到一个用pair<S::iterator,S::iterator>表示的区间,记为[p1,p2),该区间刚好包含所有键为k的元素,p1==s.lower_bound(k)和p2==s.upper_bound(k)一定成立。
5.s.count(k)
得到s容器中键为k的元素个数
关联容器的列表初始化
类似于顺序容器的列表初始化方式
对于一元关联容器直接提供元素列表即可
对于二元关联容器则需要通过{key,value}元素键值对的方式实现
set<int>integer_set={
3,5,7};//以列表中int类型的元素为键创建一元集合对象
map<string,int>id_map={
{
"小明",1},{
"李华",2}};
注意事项
关联容器的插入和删除不会使任何已有的迭代器、指针或引用失效
因此,在迭代器遍历容器过程中避免使用插入和删除操作,或者操作后需要停止遍历