文章目录
Part.0 Introduction
本篇博文记录了一下笔者使用C++算法库时,常用到的一些函数。它发挥的作用就像一个字典了,以供后续使用查阅。
Part.I algorithm
处于头文件#include <algorithm>
中,提供一组常用算法实现的函数,包括置换、排序、合并和搜索。官网中常用的函数列表如下:
查找操作
函数 | 含义 |
---|---|
*min_element(v.begin(), v.end()) | 找到v 的[begin,end) 范围内的数据的最小值 |
*max_element(v.begin(), v.end()) | 找到v 的[begin,end) 范围内的数据的最大值 |
min()/max() | 返回最小值/最大值,传入参数可以是两个简单类型的数,也可以是一个数组,但是不能是容器,容器要用上面的。 |
minmax() | 返回最大最小值 |
find(v.begin(),v.end(),key) | 在v 的[begin,end) 范围内的数据中寻找key ,找到就返回值为key 的迭代器,否则返回end |
count(v.begin(),v.end(),key) | 在v 的[begin,end) 范围内统计key 值的个数 |
mismatch(v1.begin(), v1.end(), v2); | 返回v1 的[begin,end) 范围内的数据是否和v2 一样,返回第一次不一样的数据,返回值是一个pair |
equal(v1.begin(), v1.end(), v2); | 判断v1 的[begin,end) 范围内的数据是否和v2 一样。一样返回true 否则返回false |
is_permutation(v1.begin(), v1.end(), v2.begin()) | 判断v1 的[begin,end) 范围内的数据是否和v2 所包含的元素一样,顺序不一样也可以。一样返回true 否则返回false |
search(v1.begin(), v1.end(), v2.begin(), v2.end(),) | 在v1 的[begin,end) 范围内搜索数据段与v2 的[begin,end) 相等的,返回v1 中和v2 相匹配的数据段的首元素的迭代器,找不到返回v1.end() 。 |
search_n(v.begin(),v.end(),n,tar) | 在v 的[begin,end) 范围内找n 个目标数据tar ,找到则返回第一个tar 的迭代器 |
shuffle(v.begin(), v.end() | 打乱v 的[begin,end) 范围内的数据顺序 |
all_of(v.begin(), v.end(),func) | 判断v 的[begin,end) 范围内的数据是否都满足条件func ,如果是返回true 否则返回false |
any_of(v.begin(), v.end(),func) | 判断v 的[begin,end) 范围内的数据是否存在满足条件func 的数据,若存在返回true 否则返回false |
none_of(v.begin(), v.end(),func) | 判断v 的[begin,end) 范围内的数据是否都不满足条件func ,如果都不满足返回true 否则返回false |
修改操作
函数 | 含义 |
---|---|
transform(v1.begin(), v1.end(), v2.begin(), op_increase); | 将v1 的[begin,end) 范围内的数据经过操作op_increase 后赋值给v2 |
replace(v.begin(), v.end(), a, b); | 将v 的[begin,end) 范围内的数据中的a 替换为b |
fill(v.begin(),v.begin()+4,5); | 将v 的[begin,begin+4) 范围内的数据值都设为5 |
remove(v.begin(), v.end(),rm) | 将v 的[begin,end) 范围内值为rm 的数据都删除 |
reverse(v.begin(),v.end()) | 将v 的[begin,end) 范围内的数据翻转 |
unique (v.begin(), v.end()) | 将v 的[begin,end) 范围内的数据唯一化 |
rotate(v.begin(),v.begin()+3,v.end()) | 将v 的前3个元素放到末尾,其相对顺序保持不变 |
排序操作
函数 | 含义 |
---|---|
sort(v.begin(),v.end(),cmp) | 将v 的[begin,end) 范围内的数据按照规则cmp 进行升序排列,反序可以用反向迭代器rbegin |
is_sorted(v.begin(),v.end()) | 判断v 的[begin,end) 范围内的数据是否已经是排好序的 |
二分查找
函数 | 含义 |
---|---|
lower_bound(v.begin(), v.end(), tar); | 在已排序的v 的[begin,end) 范围内查找值小于tar 的元素,返回最后一个比tar 小的元素的迭代器+1 |
upper_bound(v.begin(), v.end(), tar) | 在已排序的v 的[begin,end) 范围内查找值小于等于tar 的元素,返回第一个大于tar 的迭代器 |
equal_range(v.begin(), v.end(), tar); | 返回v 的[begin,end) 范围内数据等于tar 的数据范围,返回的是一个pair ,[pair.first,pair.second) 范围内的数据都等于tar |
binary_search(v.begin(), v.end(), tar) | 在v 的[begin,end) 范围内,以二分查找的方式寻找tar ,找到返回true 否则返回false |
堆
函数 | 含义 |
---|---|
make_heap(v.begin(),v.end()) | 将v 进行元素排序,默认大顶堆 |
pop_heap(v.begin(),v.end()); | 弹出顶上元素 |
push_heap(v.begin(),v.end()); | 向堆中加入元素 |
sort_heap(v.begin(),v.end()); | 对堆中的元素进行排序 |
is_heap(v.begin(),v.end()); | 判断它是不是堆 |
其他
函数 | 含义 |
---|---|
merge(v1,v1+5,v2,v2+5,v.begin()); | 将v1 和v2 升序合并在一起 |
includes(v1,v1+10,v2,v2+4) | 判断v1 是否包含v2 |
set_union(v1, v1+5, v2, v2+5, v.begin()); | 取v1 和v2 的合集存于v |
set_intersection(v1, v1+5, v2, v2+5, v.begin()) | 取v1 和v2 的交集存于v ,返回交集最后一个元素的迭代器+1 |
set_difference(v1, v1+5, v2, v2+5, v.begin()) | 取v1 减v2 的差集存于v |
set_symmetric_difference(v1, v1+5, v2, v2+5, v.begin()) | 取v1 与v2 的互差集存于v ,set_difference 只包含v1 不包含v2 的元素,它都包含,就是不包含公共的元素。 |
lexicographical_compare(v1,v1+5,v2,v2+9) | 比较v1 与v2 的大小,默认小true |
next_permutation(v,v+3) | 将v 变为其下一次置换,尽可能小数在前 |
pre_permutation(v,v+3) | 将v 变为其上一次置换,尽可能小数在前,否极泰来 |
Part.II numeric
处于头文件#include <numeric>
中,定义了常用的数学实现函数。官网中一共5个函数,列表如下:
函数 | 含义 |
---|---|
accumulate(v.begin(),v.end(),0); | 返回v 的[begin,end) 范围内的数据累加和 |
accumulate(v.begin(),v.end(), init, std::minus<int>()) | 返回初始值init 减去v 的[begin,end) 范围内的数据所得到的结果。可以看到第四个参数默认是加法std::plus<int>() ,这里是减法,还可以是乘法std::multiplies<int>() ,除法std::divides<int>() ,或者自己定义的运算myfunc |
adjacent_difference(v.begin(),v.end(), result, minus<int>()) | v 的[begin,end) 范围内的数据相邻元素进行std::minus<int>() 操作(后一个减前一个,首项不变,默认是减法,当然也可是其他运算),第三个参数是返回结果。 |
inner_product(v1.begin(),v1.end(), v2, init,minus<int>(),divides<int>()); | v1 的[begin,end) 范围内的元素和v2 做内积(默认相乘相加),加到初始值为init 上,并返回结果。当然这里是相减相除,也可以是自己定义的运算。 |
partial_sum(v.begin(),v.end(), result, std::multiplies<int>()); | v 的[begin,end) 范围内的数据进行前缀和(部分和)multiplies 运算(默认是加法),并将结果赋值给result |
std::iota(v.begin(),v.end(),init); | 将init 顺次增加1赋值给向量v ,包括init |
Part.III functional
处于头文件#include <functional>
中,定义了许多函数对象类型和支持函数对象的功能。因为里面的函数实现大多是为别的类中的函数提供便利和支持的,因此就不详细列举了(像加-减-乘-除-模-非[反号] plus
-minus
-multiplies
-divides
-modulus
-negate
都是在里面定义的),详细介绍可看官网。
Part.IV memory
处于头文件#include <memory>
中,给容器、管理内存的函数和auto_ptr
模板类定义标准内存分配器。官网中常用的函数列表如下:
函数 | 含义 |
---|---|
T* allocate(size_t n); | 分配足够的存储空间来存储T的n个实例,并返回指向它的指针 |
auto sp = std::make_shared<int>(); | 分配堆空间,创建智能指针make_shared ,用指针鼓励用这个,不要用new |
- 之前我一直以为
memcpy
和sizeof
是在这个头文件中包含的,但是后来发现并没有,sizeof
是C++的一个关键字,memcpy
是在string.h
中定义的。
Part.V iterator
处于头文件#include <iterator>
中,给迭代器(可以将其简单理解为指针,*itr
可以获取迭代器itr
所指向的值)提供定义和支持。官网中常用的函数列表如下:
函数 | 含义 |
---|---|
advance(it,n); | 将迭代器itr 前移n 个单位。比如itr 一开始指向索引1 ,那么执行此条指令后其指向索引1+n |
distance(v.begin(),itr) | 返回迭代器itr 到迭代器v.begin() 的距离 |
begin(container) | 返回容器container 的最开始索引 |
begin(container) | 返回容器container 的最后的索引,注意一般end() 指示的是容器的尾部,并不指向任何一个值 |
prev(itr) | 返回迭代器itr 前面的一个迭代器 |
next(itr) | 返回迭代器itr 后面的一个迭代器 |
Part.VI utility
处于头文件#include <utility>
中,定义重载的关系运算符,简化关系运算符的写入。官网中常用的函数列表如下:
函数 | 含义 |
---|---|
swap(a,b) | 交换a 和b 的值,只要他们两个类型相同就可以交换 |
make_pair(x,y) | 返回(x,y) 组成的pair |