c++入门学习⑨——STL(万字总结,超级超级详细版)看完这一篇就够了!!!
目录
🎄前言
🎄概念
引入
定义
优点
🎄六大组件
容器
算法
迭代器
仿函数
适配器
空间配置器
🎄三大组件
迭代器(iterator)
定义
分类:
正向迭代器:
常量正向迭代器:
反向迭代器:
常量反向迭代器:
用法:
🎄STL常用容器
介绍:
分类
作用
常用容器:
Vector容器
介绍:
构造/初始化
常用迭代器和遍历方法
特殊遍历案例:
赋值
大小、容量
插入删除操作
元素访问和存取方式
vector容器互换操作的扩展使用
vector容器的预留问题
string容器
补充概念
概念
特点
构造
赋值
拼接
查找和替换
字符串比较
存取
插入删除
子串
deque容器
概念:
deque与vector区别:
工作原理:
赋值
大小
插入和删除操作
查找存取
排序
stack容器
构造
赋值
存取
大小
代码示例:
编辑
queue容器
构造
赋值
存取
大小
代码示例:
list容器
创建
赋值
大小
插入和删除
存取
迭代器
排序
set容器/multiset容器
简介
区别
构造
赋值
大小
插入和删除
统计数据
sort排序规则如何改变
pair对组
两种创建方式:
map容器/multimap容器
简介
本质
优点
区别
构造和赋值
大小
插入和删除
查找
变排序规则
🎄STL函数对象
函数对象
概念:
区别和共性:
谓词
而且分为两类:
内置的函数对象
分类:
算数仿函数
关系仿函数
逻辑仿函数
🎄STL算法
常用算法:
1.遍历算法
for_each
transform
2.查找算法
find
find_if
adjacent_find
binary_search
count
count_if
3.排序算法
sort
random_shuffle
merge
reverse
4.拷贝和替换函数
copy
replace
replace_if
swap
5.算术生成算法
fill
accumulate
6.集合算法
set_intersection
🎄总结
🎄前言
本篇博客主要介绍有关STL的知识,设计常用容器及常用算法等知识,内容细节会比较多,也比较细,希望对大家有所帮助。(●'◡'●)
文章会不定时更新细节,欢迎继续关注。
🎄概念
引入
复用性,这个是软件界希望达到的一个性能。
而复用性必须建立在某种标准下,
为了建立数据结构和算法的一套标准,而且降低他们的相互胶着的性质,而提升他们的独立性、弹性、交互操作性、因此在这个环境下,STL诞生了。
STL几乎所有代码都是用模板类和模板函数,提高了代码的重用性。
c++标准程序库中隶属于STL的已经超过百分之八十以上。
定义
STL(Standard Template Library)——每个字母分别代表标准、模板、库
STL不是面向对象的编程——而是一种不同的编程模式——通用编程技术
优点
不需要额外安装
高可重用性,高移植性,跨平台性
将数据和操作分离,数据由容器类别加以管理,
程序员不需要直到它的据体实现过程,只需要可以熟练使用即可
🎄六大组件
STL提供了六大组件,彼此之间可以组合套用。
容器、算法、迭代器、仿函数、适配器、空间配置器
容器
各种数据结构,用来存放数据,实现角度来看,STL容器实际上是一种类模板
算法
各种各样的算法,功能模板
迭代器
容器和算法的胶着剂,分为五种类型
每个容器都有自己的迭代器,初学阶段可以把它看为指针
仿函数
行为类似函数,可作为算法的某种策略,从实现角度来看,仿函数是一种重载了operator()的class或者是类模板
适配器
修饰容器或是仿函数或迭代器接口的东西
空间配置器
负责空间的配置和管理,
而其中的前三个组件是STL广义上的分类,主要重点就集中在这三个上
🎄三大组件
三大组件的关系——容器和算法通过迭代器来进行无缝连接,算法通过迭代器访问容器中的元素
实际上,所谓容器是存储数据的地方,而算法是操作,操作需要对数据进行,这时候需要迭代器来使这两个联系起来
迭代器(iterator)
定义
迭代器可以指向容器中的某个元素,通过迭代器可以指向容器中的元素,通过迭代器可以读写它指向的元素——因此它在某方面很像指针,初学者可以先把它看成指针使用
它是一种广义指针,它是一个可以完成类似指针操作的对象
迭代器是一个接口,指向容器的数据,然后算法通过这个迭代器去实现对容器的操作,相当于一个容器和算法的粘合剂
不同的容器通常有着自己的迭代器,迭代器的类型是一个iterator的typedef类型,作用域为整个类。
分类:
正向迭代器:
容器类名::iterator 迭代器名
常量正向迭代器:
容器类名::const_iterator 迭代器名
反向迭代器:
容器类名::reverse_iterator 迭代器名
常量反向迭代器:
容器类名::const_reverse_iterator 迭代器名
用法:
前面已经说过,它指向某个元素,可以看为指针,那*迭代器名就可以表示迭代器所指的元素了。
而每一个容器都有它自己的迭代器,根据不同迭代器指向的位置的不同,可以进行不同的用途,具体用法在下面容器中介绍——
🎄STL常用容器
介绍:
任何数据结构都是为了实现某种特定算法,STL容器就是将运用最广泛的一些数据结构实现出来,
例如——数组、链表、树、栈、队列、集合、映射表
他们可以根据在容器种的排列特性来分类——
分类
序列式——需要注意数据存储时的数据顺序
每个元素均有固定的位置,除非用删除或是插入改变这个位置,Vector容器,Deque容器,List容器等
关联式——不需要关心其顺序
非线性的树结构,二叉树结构,特点是——在值中选择一个树作为关键字key,起索引作用,Set和Map容器
作用
常用容器:
Vector容器
介绍:
- vector是将元素置于一个动态数组中加以管理的容器,可以随时添加数值和删除元素,存放内置数据类型
- vector可以随机存取元素
- vector尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比较费时
⭐注意:在局部区域中创建vector数组,在堆空间里开——因为栈区比较小,假如放非常长的数组会发生爆栈,因此局部区域不可以开大长度数组,但是可以开大长度vector
包含头文件——#include
⭐与数组的区别:vector可动态分配
动态分配——vector先开辟一块空间,然后假如需要的空间大于这个开辟的空间了,vector不会在原有空间后面再开辟一块空间,而是在其他地方再找一块空间,然后把原有空间的值给复制到这个新空间,然后插入需要的值,这种方法导致——原有的迭代器将没用了,它们指向的不是这个新的空间,而老的空间已经报废了,因此这个动态内存分配会出现这个问题
vector的迭代器是随机访问的迭代器
构造/初始化
vector容器采用模板构造
//1.默认构造 vector 数据名 //示例: vector a;//定义了一个叫a一维数组,而且数组存储结构体类型数据 //2.带参数的构造 vector 数据名(n)//n代表这个数组长度为n vector 数据名(beg,end)//把beg到end区间里的所有元素赋值给这个,其中区间是左闭右开 //示例: vector b(n);//定义一个长度为n的数组,初始的默认值都为0,下标从0到n-1 //如果想指定初始化值 vector b(n,1)//初始的默认值都为1了 //3.初始化多个元素 vector 数据名{数据}//定义一个数组,里面有的数据由定义时的{}里的数据决定 //4.拷贝初始化 vector a(5,0)//定义一个数组,长度为5,初始值都为0 vector b(a);//把a的所有数据都拷贝到b上,前提是所对应的b数组中的类型相同 vector c=a;//c和a一样了 //5.二维构造 vector a[10];//这里是定义一个第一维的长度为10且固定,而第二维可变化的二维数组 vector b;//第一维第二维均可变 vector c(n,vector(m,0))//均固定,且初始值都为0这里一般的都好理解,有一点难度的是嵌套构造——
vector a
这个是一种嵌套构造方式,其中a它的每一个元素都是整型动态数组。
vector容器嵌套可以使用下标方式访问——前提是必须初始化一维数组的数量
vectora(3,vector(4,'\0'))拷贝构造函数,区间拷贝构造函数
自定义:vector(行数,vector())
常用迭代器和遍历方法
数组名称.begin()
返回首元素的迭代器——地址
数组名称.end()
返回最后一个元素的后一个位置的迭代器——地址
数组名称.empty()
判断是否为空,空则返回真,反之返回假
数组名称.push_back()
在尾部插入值
数组名称.pop_back()
删除最后一个值
数组名称.clear()
数组名称.resize()
重新指定大小
数组名称.size()
返回数组的大小
数组名称.erase()
清除数组中的一些元素
补充:STL函数——排序
sort(beg,end).对区间beg到end里的数据从小到大排序
使用反向迭代器降序排序
遍历方法:
1.for循环来遍历
先使用函数,引用传参,在函数里放一个for循环,设置一个迭代器指向数组的开始,让这个迭代器不等于数组的最后,且每次执行都要加一次1.
代码如下:
void bl(vector& a) { for (vector::iterator it = a.begin(); it != a.end(); it++) { cout
