
C/C++ 语法教程(14)——STL 简介(1)
C++ STL
时隔 n 年我又来更新啦!
STL 组成
主要就三种:容器、算法和迭代器。
听起来很高大上,然而也不用知道这么多。
C++ 常用算法
一般只需要 #include <algorithm>
即可调用(当然请不要忘记 using namespace std;
,否则你可能每个函数或方法都需要前置 std::
)。
一、sort()
一般的使用中 sort()
传入两个参数,分别代表首地址和尾地址后一位,在学过后面的容器之后,也可以使用对应的迭代器,如:
这里的第一个就是将 a[0]
至 a[n-1]
从小到大排序,后两个则是使用了容器的对应迭代器,同样从小到大排序。
这里默认的排序是利用 <
进行。
当然在没有定义 <
或者需要排序依据不同时也可以传入第三个参数,也就是比较函数(可以是一般的函数,或者函数对象,或者 lambda 函数)。
比如想从大到小排序,可以有许多种写法:
这四种甚至其他更多方法都是可以的。(不知道函数对象不急,会前两种就行)
可以发现 C++ STL 的使用方法非常多样化,这是因为 STL 本身就是面向对象的,所以对于不理解的部分完全可以在学过面向对象后再来尝试阅读。
除此之外还有 stable_sort()
和 partial_sort()
,它们分别可以做到:
- 不改变原来序列中相等元素相对顺序的情况下排序。
- 挑出最小的若干个(指定)元素,排序完并置于最前面。
具体可以自行了解。
二、nth_element()
这个函数跟 sort()
极为类似,只不过在 sort()
前两个参数之间新增了一个参数。
比如:
这代表将 a[]
数组中第 i+1 小的放至 a[i]
,并使得 a[0]
至 a[i-1]
均小于等于 a[i]
,a[i + 1]
至 a[n-1]
均大于等于 a[i]
。
同样可以自定义比较函数。
特别注意,这个函数的时间复杂度为 O(n)。
三、lower_bound()
和 upper_bound()
这样的调用会返回 a[0]
到 a[n-1]
中第一个不小于 x 的元素的指针。
当然前提是 a[]
数组已经升序排列。
这里的前两个参数还是可以跟上面所说一样,也同样可以自己给出升序的比较函数。
而 upper_bound
唯一的区别,便是变为找到第一个大于 x 的元素的指针。
四、其他常用算法
比如 next_permutation()
、prev_permutation()
、unique()
、is_sorted()
、replace()
等等。
这些算法(函数)功能奇特,但是相对不那么常用,还想了解可以点这里自己学习。
迭代器
一、迭代器分类
主要分为五类:
迭代器类型 | 迭代器特征 |
---|---|
Input iterator(输入迭代器) | 读,不能写;只支持自增运算 |
Output iterator(输出迭代器) | 写,不能读;只支持自增运算 |
Forward iterator(前向迭代器) | 读和写;只支持自增运算 |
Bidirectional iterator(双向迭代器) | 读和写;支持自增和自减运算 |
Random access iterator(随机访问迭代器) | 读和写;支持完整的迭代器算术运算 |
具体来说:
- 输入迭代器:支持
++
(前后置均可)、==
、!=
、*
(仅作为右值(赋值语句右侧))、->
。 - 输出迭代器:支持
++
(前后置均可)、*
(仅作为左值(赋值语句左侧))。 - 前向迭代器:支持上述两种所有操作,且可以通过预先备份返回原位置,也就是可以多次访问同一位置。
- 双向迭代器:除上述外,还支持
--
(前后置均可)。 - 随机访问迭代器:提供在常量时间内访问容器任意位置的功能,额外支持
<
、>
、<=
、>=
、+
、-
、+=
、-=
,以及两个迭代器相减可以得到距离,iter[n]
依然等价于*(iter+n)
。
二、迭代器与算法
在算法中传递的迭代器或者获得的迭代器也是会有要求,可以根据算法特点分别判断,因为具体而言太过复杂,就不写了。
三、迭代器与指针
- 迭代器不是指针,是类模板,表现的像指针。它只是封装了某些运算符(方法之后会讲),从而表现得像指针。
- 迭代器返回的是对象引用而不是对象的值,所以
cout
只能输出迭代器使用*
取值后的值而不能直接输出其自身。 - 迭代器可以提供一种在不需要暴露某个容器的内部表现形式情况下,依然能依次访问该容器中的各个元素的方法。
- 指针能指向函数而迭代器不行,迭代器只能指向容器。
- 有时候可以认为指针是迭代器的一种,指针只能用于某些特定的容器,而迭代器是指针的抽象和泛化。所以,指针满足迭代器的一切要求。
string
类
需要包含头文件 <string>
(同样最好 using namespace std;
)。
一、基础使用
定义和输入输出一个 string
类型变量可以采用:
二、构造函数和析构函数
有如下几种定义并构造 string
型变量的方法:
最常见的就是:
同样还有析构函数(大概就是销毁这个变量的方法):
三、获取长度
一般使用 .size()
或者 .length()
方法即可。
比如:
就会输出 3。
四、获取对应元素
可以使用 s[i]
的方法获取 string s
的第 i 个字符,当然也可以使用 s.at(i)
的写法。
一般来说 s.at(i)
的写法更安全一些,当然如果保证程序无问题就不用考虑这么多。
(.at()
方法是返回引用的函数,所以也可以作为左值(赋值运算符左侧))
五、比较方法
C++ STL 中内置了 string
的 <
、>
、==
、<=
、>=
、!=
的比较运算符,而且不止可以在 string
类型之间使用,还可以比较 string
和 char *
类型,可以直接使用,但是请不要对空字符串使用这些比较运算符,否则程序很可能异常退出。
当然还有专门的函数:
具体使用方法可以自己查询尝试。
举个例子:
结果是:
m = 1, n = -1, p = -1, q = 0
六、相关迭代器
string
类型的迭代器是随机存取迭代器,常用迭代器有:
string::iterator s.begin()
:表示字符串开始位置,指向s[0]
;string::iterator s.end()
:表示字符串结束位置,指向s
的最后一个字符之后一位(不能用*
运算符);string::reverse_iterator s.rbegin()
:表示字符串反转(abc
反转后为cba
)后的开始位置。string::reverse_iterator s.rend()
:表示字符串反转后的结束位置。
七、字符串内容修改和替换
前置知识(或者叫强行插入):
- 可以使用
s.c_str()
方法获取将string
转为char *
类型后的值。 string::npos
表示此类型可表示最大数(因为是无符号整型,相当于值为 −1),可认为无穷大。
首先可以通过获取对应元素并直接赋值的方法,也可以直接使用 =
运算符赋值。
除此之外,还有 assign()
、erase()
、swap()
、insert()
、append()
、replace()
,详细使用方法直接看例子:(重点是掌握足够多的的方法使得无论遇到什么需求都可以应对,不是每种都需要记下来)
输出结果是:
123456
456
3456
XXXXX
12345
123456
123
::
abcdefghijklmn
Hello
插入: Hyan
插入:Hlo
插入:HCCCCC
插入:Hello
A = ello, B = H
追加:Hello
A = ello, B= H
追加:H12
A = ello, B= H
追加:H345
A = ello, B = H
追加:Haaaaaaaaaa
A = ello, B = H
追加:Hello
1: abc1234ghijklmn
2: abc234efghijklmn
3: abcxxxxxefghijklmn
4: 1234
5: 67891234efghijklmn
6: abc1234efghijklmn
需要注意的是,以上长度不足的,大多是取到字符串结束为止,但可能有部分出入,建议具体自行尝试。
八、字符串查找
主要由 find()
和 rfind()
两种函数,分别是正向查找和逆向查找,返回值为第一次查找成功时,开始匹配上的位置(类型是 string::size_type
也就是无符号整型!),如果未能找到返回 string::npos
。
除此之外的几个函数使用较少,不展开叙述。
举几个例子:
输出结果如下:
Example - find() : The position (forward) of 'P' is: 5
Example - rfind(): The position (reverse) of 'P' is: 5
Example - find () : The position (forward) of 'some' is: 35
Example - rfind () : The position (reverse) of 'some' is: -1
Example - find(): The position (forward) of 'drugs' is: 40
Example - rfind(): The position (reverse) of 'drugs' is: -1
Example - find (): The position of 'for' is: 46
Example - rfind(): The position of 'for' is: -1
理论上还有 string
的配置器等内容,然而我这个是真的啥也不会,就不献丑了。
习题
由于作者已经被这些乱七八糟的 STL 搞自闭了,所以上演习题消失大法。
行吧,这真的上面这些够练习了,不多说了,我自己先学会。
No Comments