STL讲课讲义

C++部分基础 与 STL

写在前面: 本文仅针对C++STL进行基础展开, 包含许多容器的基础用法 及 基础函数.

额外的, 若无特殊说明, 文中涉及到的复杂度, 默认为时间复杂度, 且是均摊意义上的. 复杂度中的 n n n默认为大小/长度, l o g log log默认为 l o g 2 log_2 log2, 其余变量均认为与 n n n同阶.

1. 引用 and 模版

1). 引用

&: 类似指针. 可以理解为给某个变量起了别名.

特别的: 一旦引用某个变量后, 不可再修改(不同于指针).

2). 模版类

常规类变量定义方式: className variableName;

模版类变量定义方式: className<typeName> variableName;

3). 模版函数

常规函数调用方式: functionName(parameter…);

模版函数调用方式: functionName<typeName>(parameter…);


2. string 字符串

常用函数

设字符串长度为 n n n.

string::npos: 定义在<string>头文件内, 值为ULONG_MAX. 其中::称为作用域运算符.

函数名作用参数说明复杂度备注
size() / length()得到字符串长度NULL O ( 1 ) O(1) O(1)返回值为UL类型, 表示字符串长度.
empty()判断字符串是否为空NULL O ( 1 ) O(1) O(1)返回值为bool类型. 为空返回 1 1 1, 否则返回 0 0 0
find(str)查找某个字符串是否出现传入一个字符串 O ( n 2 ) O(n^2) O(n2)返回值为UL类型. 表示找查字符串str第一次在原串中出现的下标. 若找不到, 则返回string::npos.
c_str()返回一个const char*类型字符串NULL O ( n ) O(n) O(n)常用于以C语言方式输出string内容
pop_back()删除最后一个字符NULL O ( 1 ) O(1) O(1)NULL

关于find()函数, 很多人喜欢通过 判断返回值是否为 − 1 -1 1来判断是否出现过该字符串, 这种写法可以做到正确的判断.

原因: − 1 -1 1int类型, 当find()找不到时, 其返回值是unsigned long类型的最大值, 在二者比较时, 会隐式转化为UL进行比较, 两者的值的确是相同的(此处推荐以计算机存储数据的二进制补码形式去想). 什么? 在您的电脑上不相等? 那您的机器一定老有收藏价值了!

额外的, 通过str[index]来访问位于 i n d e x index index位置的字符.

可通过> < >= <= ==来比较字符串字典序等.

Tips: string也是支持迭代器的.



容器适配器

1. queue 单向队列

用于存放需要顺序执行的进程.

定义: queue<类型名> 变量名;

常用函数
函数名作用参数说明复杂度备注
size()得到队列长度NULL O ( 1 ) O(1) O(1)返回值为UL类型, 表示队列中元素个数.
empty()判断队列是否为空NULL O ( 1 ) O(1) O(1)返回值为bool类型. 为空返回 1 1 1, 否则返回 0 0 0
push(val)把元素存入队尾传入要存入队列的值 O ( 1 ) O(1) O(1)若传入变量, 相当于是以值传递的形式进行存储.
pop()删除队首元素NULL O ( 1 ) O(1) O(1)NULL
front()得到队首元素NULL O ( 1 ) O(1) O(1)只取出该元素, 并不会从队列中删除该元素. 需要用pop()函数手动删除.

2. stack 栈

用于存放需要递归执行的进程

定义: stack<类型名> 变量名;

常用函数
函数名作用参数说明复杂度备注
size()得到栈大小NULL O ( 1 ) O(1) O(1)返回值为UL类型, 表示栈中元素个数.
empty()判断栈是否为空NULL O ( 1 ) O(1) O(1)返回值为bool类型. 为空返回 1 1 1, 否则返回 0 0 0
push(val)把元素存入栈顶传入要存入栈的值 O ( 1 ) O(1) O(1)若传入变量, 相当于是以值传递的形式进行存储.
pop()删除栈顶元素NULL O ( 1 ) O(1) O(1)NULL
top()得到栈顶元素NULL O ( 1 ) O(1) O(1)只是取出该元素, 并不会从栈中删除该元素, 需要用pop()函数手动删除.

3. priority_queue 优先队列/堆

类似于普通队列, 但是会自动按照优先级从高到低排序队列内元素.

定义: priority_queue<类型名> 变量名;

常用函数
函数名作用参数说明复杂度备注
size()得到堆大小NULL O ( 1 ) O(1) O(1)返回值为UL类型, 表示堆中元素个数.
empty()判断堆是否为空NULL O ( 1 ) O(1) O(1)返回值为bool类型. 为空返回 1 1 1, 否则返回 0 0 0
push(val)把元素存入堆中传入要存入堆的值 O ( l o g n ) O(logn) O(logn)若传入变量, 相当于是以值传递的形式进行存储.
pop()删除堆顶元素NULL O ( l o g n ) O(logn) O(logn)NULL
top()得到堆顶元素NULL O ( 1 ) O(1) O(1)只取出该元素, 并不会从堆中删除该元素. 需要用pop()函数手动删除.


顺序容器

0. 迭代器

0). 迭代器用法

​ 迭代器的定义: 容器类名::iterator 变量名;

​ 迭代器的访问: *迭代器变量

可以把迭代器看作指针, 只不过针对于STL, 起了个不一样的名字.

1). 双向迭代器

可以双向移动的迭代器. 对于当前迭代器而言, 每次只能移动到其前一个迭代器, 或后一个迭代器.

2). 随机访问迭代器

随机访问迭代器是可以随机访问容器中的元素的双向迭代器. 对于当前迭代器而言, 可以向前, 向后移动任意多个迭代器.

3). 容器中迭代器的获取方式

支持迭代器的容器可以通过begin(), end()函数分别得到首尾迭代器,
特别的, 部分类函数也会以迭代器作为返回值.

函数名作用复杂度备注
begin()得到首迭代器 O ( 1 ) O(1) O(1)NULL
end()得到尾迭代器 O ( 1 ) O(1) O(1)该函数所返回的尾迭代器, 实质是指向容器内尾元素的后一个位置. 该位置不应该被访问到, 否则会出错.

我们可以通过迭代器遍历 [ b e g i n , e n d ) [begin, end) [begin,end)来遍历整个容器.

特别的, 通常情况下, 请使用前缀运算符来移动迭代器, 这样可以避免临时变量的产生, 从而加快程序运行速度.


1. vector 可变长数组

顺序容器的一种, 迭代器类型为随机访问迭代器.

定义: vector<类型名> 变量名;

常用函数
函数名作用参数说明复杂度备注
size()得到数组长度NULL O ( 1 ) O(1) O(1)返回值为UL类型, 表示数组中元素个数.
push_back(val)向数组末端添加元素传入要存入数组的值 O ( 1 ) O(1) O(1)若传入变量, 相当于是以值传递的形式进行存储.
pop_back()删除数组末端元素.NULL O ( 1 ) O(1) O(1)NULL
clear()清空整个数组NULL O ( n ) O(n) O(n)NULL

额外的, 同于普通数组, 我们也可以通过[]来访问数组中元素, 下标从 0 0 0开始.

常见错误: vector并不同于常规的静态数组, 其内部的空间必须先开辟, 后使用.


2. deque 双向队列

顺序容器的一种, 迭代器类型为随机访问迭代器.

可以看作是一个支持双向操作的vector. (虽然叫双向队列, 但或许叫"双向数组"更贴切一些).

定义: deque<类型名> 变量名;

常用函数
函数名作用参数说明复杂度备注
size()得到数组长度NULL O ( 1 ) O(1) O(1)返回值为UL类型, 表示数组中元素个数.
push_back(val)数组末端添加元素传入要存入数组的值 O ( 1 ) O(1) O(1)若传入变量, 相当于是以值传递的形式进行存储.
pop_back()删除数组末端元素.NULL O ( 1 ) O(1) O(1)NULL
push_front(val)数组首端添加元素传入要存入数组的值 O ( 1 ) O(1) O(1)若传入变量, 相当于是以值传递的形式进行存储.
pop_front()删除数组首端元素.NULL O ( 1 ) O(1) O(1)NULL
clear()清空整个数组NULL O ( n ) O(n) O(n)NULL

额外的: 同样可以通过[]来访问数组中元素, 下标从 0 0 0开始.

常见错误: 双向队列的存储方式并不是直觉上的在内存中线性依次存储, 有可能数组尾端的元素在内存地址较小的位置. 因此在访问迭代器时, 谨防越界.


3. list 双向链表

顺序容器的一种, 迭代器类型为双向迭代器.

定义: list<类型名> 变量名;

常用函数
函数名作用参数说明复杂度备注
size()得到链表长度NULL O ( 1 ) O(1) O(1)返回值为UL类型, 表示链表中元素个数.
push_back(val)链表末端添加元素传入要存入数组的值 O ( 1 ) O(1) O(1)若传入变量, 相当于是以值传递的形式进行存储.
pop_back()删除链表末端元素.NULL O ( 1 ) O(1) O(1)NULL
push_front(val)链表首端添加元素传入要存入数组的值 O ( 1 ) O(1) O(1)若传入变量, 相当于是以值传递的形式进行存储.
pop_front()删除链表首端元素.NULL O ( 1 ) O(1) O(1)NULL
insert(it, val)向链表指定迭代器之前插入元素传入 迭代器 及 元素值 O ( 1 ) O(1) O(1)若传入变量, 相当于是以值传递的形式进行存储.
erase(it)删除链表指定迭代器位置的元素传入 迭代器 O ( 1 ) O(1) O(1)NULL
clear()清空整个链表NULL O ( n ) O(n) O(n)NULL
front()得到链表首元素NULL O ( 1 ) O(1) O(1)得到的实质上是首元素的引用
back()得到链表尾元素NULL O ( 1 ) O(1) O(1)得到的实质上是尾元素的引用
sort()将链表排序NULL O ( n l o g n ) O(nlogn) O(nlogn)NULL
unique()将有序链表去重NULL O ( n ) O(n) O(n)会自动删除尾部多余的元素
merge(list)合并两个有序链表传入需要被合并的链表 O ( n ) O(n) O(n)会自动清空被合并的链表
reverse()将链表内元素翻转NULL O ( n ) O(n) O(n)NULL

特别的, 在c++11标准前, size()函数的实现复杂度为 O ( 1 )   /   O ( n ) O(1) \ / \ O(n) O(1) / O(n).

list并不作为ACM的重点考察, 但是其内部的许多函数均在<algorithm>等头文件内均有通用形式.


关联容器

1. set / multiset 集合 / 可重集合

关联容器的一种, 迭代器类型为双向迭代器.

集合会对其内部元素自动排序, 默认按照less规则排序. 底层实现为红黑树.

定义: set<类型名> 变量名;, multiset<类型名> 变量名;

常用函数(部分函数set与multiset中不同, 标有*的部分应在multiset中特殊注意)
函数名作用参数说明复杂度备注
size()得到集合大小NULL O ( 1 ) O(1) O(1)返回值为UL类型, 表示集合中元素个数.
clear()清空整个集合NULL O ( n ) O(n) O(n)NULL
insert(val)向集合中插入元素NULL O ( l o g n ) O(logn) O(logn)若传入变量, 相当于是以值传递的形式进行存储.
erase(val)删除集合中等于传入值的元素传入元素值 O ( l o g n ) O(logn) O(logn)*会删除全部值为val的元素!
erase(it)删除集合中位于该迭代器位置的元素传入迭代器 O ( 1 ) O(1) O(1)*常用于删除multiset中的单个重复元素.
find(val)查询集合中是否有等于传入值的元素.传入元素值 O ( l o g n ) O(logn) O(logn)*会返回第一个符合条件的迭代器. 若找不到, 则返回end迭代器
count(val)查询集合中等于传入值的元素个数传入元素值 O ( l o g n ) O(logn) O(logn)*返回UL类型. 在set中, 结果只会是 0 / 1 0/1 0/1
lower_bound(val)查询集合中第一个大于等于传入值的元素传入元素值 O ( l o g n ) O(logn) O(logn)返回迭代器. 若找不到则返回end迭代器.
upper_bound(val)查询集合中第一个严格大于传入值的元素传入元素值 O ( l o g n ) O(logn) O(logn)返回迭代器. 若找不到则返回end迭代器.

0. pair 对组 / 二元组

不属于关联容器.

作用: 把两种类型结合成一种新类型.

当然, 结构体可以做的更为广泛. 你可以把pair理解为一个仅有两种类型的结构体.


定义: pair<typeName1, typeName2> variableName;

访问: 通过 变量名.first访问第一个类型, 变量名.second访问第二个类型. (会返回它们的引用)

相当于一个结构体内部两个变量依次叫first second.

特别的: 可以通过函数make_pair(parameter1, parameter2)得到一个pair类型.


2. map / multimap 映射 / 可重映射 (字典)

关联容器的一种, 迭代器类型为双向迭代器.

映射同样会对其内部元素按照 k e y key key值自动排序, 默认按照less规则排序. 底层实现同样为红黑树.
映射内存储一个二元组pair, pair f i r s t first first称为 m a p map map k e y key key值, s e c o n d second second称为 m a p map map v a l u e value value值,

定义: map<类型名, 类型名> 变量名;

常用函数 (函数参数是针对于 k e y key key值而言, 标有*的部分应在multimap中特殊注意)
函数名作用参数说明复杂度备注
size()得到映射大小NULL O ( 1 ) O(1) O(1)返回值为UL类型, 表示映射中元素个数.
clear()清空整个映射NULL O ( n ) O(n) O(n)NULL
insert(val)向映射中插入元素NULL O ( l o g n ) O(logn) O(logn)插入的应是一个 ( k e y , v a l u e ) (key, value) (key,value)二元组
erase(val)删除映射中等于传入值的元素传入元素值 O ( l o g n ) O(logn) O(logn)*会删除全部值为val的元素!
erase(it)删除映射中位于该迭代器位置的元素传入迭代器 O ( 1 ) O(1) O(1)*常用于删除multimap中的单个重复元素.
find(val)查询映射中是否有等于传入值的元素.传入元素值 O ( l o g n ) O(logn) O(logn)*会返回第一个符合条件的迭代器. 若找不到, 则返回end迭代器
count(val)查询映射中等于传入值的元素个数传入元素值 O ( l o g n ) O(logn) O(logn)*返回UL类型. 在map中, 结果只会是 0 / 1 0/1 0/1
lower_bound(val)查询映射中第一个大于等于传入值的元素传入元素值 O ( l o g n ) O(logn) O(logn)返回迭代器. 若找不到则返回end迭代器.
upper_bound(val)查询映射中第一个严格大于传入值的元素传入元素值 O ( l o g n ) O(logn) O(logn)返回迭代器. 若找不到则返回end迭代器.

额外的, 在map中, 我们可以使用[key]来完成访问 v a l val val, 复杂度为 O ( l o g n ) O(logn) O(logn).
但在multimap中, 由于元素可重复, 我们只能通过 f i n d find find函数找到迭代器后, 再进行访问.

当使用[key]访问map时, 若映射中不存在该 k e y key key值, 则会自动添加该 k e y key key值至map中.



END

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++ STL 黑马讲义是一本教授C++标准模板库(STL)的教材。STLC++的一个重要组成部分,它是一组通用的数据结构和算法的集合,包括容器(containers)、迭代器(iterators)、算法(algorithms)和函数对象(function objects),可帮助我们高效地开发软件。 该讲义内容丰富,深入浅出。首先,它详细介绍了STL中各个组成部分的特点和用法。我们可以学习如何使用各种容器,如向量(vector)、链表(list)、映射(map)和集合(set),以及如何通过迭代器遍历和操作这些容器。同时,还可以了解STL提供的丰富的算法库,如排序、查找、拷贝和变换等,这些算法可以大大简化我们的编程工作。 其次,这本讲义还通过实例来演示STL的具体应用。通过这些实例,我们可以学习如何利用STL解决实际问题,如如何实现自定义的函数对象、如何使用STL算法进行排序和查找、如何使用STL容器存储和操作数据等。这些实例帮助我们更好地理解STL的概念和用法。 此外,该讲义还注重提供了一些常见问题和解答,帮助读者理解STL使用过程中可能遇到的问题和解决方法。同时,它还提供了一些性能优化的技巧和经验分享,帮助我们优化STL程序的效率。 总之,C++ STL 黑马讲义是一本全面介绍C++标准模板库的教材,它准确详实地解释了STL的各个组成部分和用法。通过学习这本讲义,我们可以更加深入地了解STL,并且能够更加熟练地运用STL开发高效的C++程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逍遥Fau

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值