STL-常用算法
算法主要由头文件
<algroithm> <functional> <numeric>
组成
<algroithm>
体量较大 涉及比较,交换,查找,遍历操作,复制,修改等等;<functional>
定义了一些模板类,用于声明函数对象;<numeric>
内容较少,只包括几个在序列上进行简单数学运算的模板函数;
常用遍历算法
for_each 算法
声明:
for_each(Iterator first, Iterator last, Function func)
for_each
本质是一个模板函数;- 该算法用于遍历容器(通过迭代器
iterator it
),并在函数内部执行操作:func(*it)
;
在func部分可以传递的参数有函数指针和仿函数- 该函数返回值为
return func;
该返回值的意义是当传递的参数是有自己状态的仿函数时 可以返回算法执行结束之后函数的状态;
transform 算法
声明及定义:
```cpp
```cpp
//一元版本:
template <typename InputIt, typename OutputIt, typename UnaryOp>
OutputIt transform(InputIt first, InputIt last, OutputIt result, UnaryOp op) {// 遍历输入范围[first, last)while (first != last) {// 对当前元素应用一元操作,并存储到结果范围*result = op(*first);// 移动所有迭代器到下一个位置++first;++result;}// 返回结果范围的末尾迭代器return result;
}//二元版本
template <typename InputIt1, typename InputIt2, typename OutputIt, typename BinaryOp>
OutputIt transform(InputIt1 first1, InputIt1 last1, InputIt2 first2,OutputIt result, BinaryOp op) {// 遍历第一个输入范围[first1, last1)while (first1 != last1) {// 对两个范围的当前元素应用二元操作,并存储到结果范围*result = op(*first1, *first2);// 移动所有迭代器到下一个位置++first1;++first2;++result;}// 返回结果范围的末尾迭代器return result;
}
transform
算法是将原来容器中的元素在进行函数op的操作之后传入到另一个容器,有一元和二元两个版本;- op可以传递函数指针也可以传递仿函数;
- 在二元版本中要求first2的容器的输入范围至少要和first1的输入范围相同,否则会出现越界访问的问题
find 算法
函数的声明如下:
template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );
find
函数用于查找一个容器中是否有与value一样的值;find
函数的返回值为迭代器类型,若在容器中找打与value匹配的元素则会返回指向该元素的迭代器,若没有找到则会返回容器的end( );
常用查找算法
find_if 算法
find_if
算法声明如下:
template< class InputIt, class UnaryPredicate >
InputIt find_if( InputIt first, InputIt last, UnaryPredicate p );
find_if
算法需要传入一个谓词作为参数,因为find_if
算法就是寻找容器中第一个符合谓词判断条件的元素;- 如果找到符合谓词条件的元素则会返回指向该元素的迭代器,若没有找到则会返回该容器的end( );
adjacent_find 算法
定义:
template< class ForwardIt, class BinaryPredicate >
ForwardIt adjacent_find( ForwardIt first, ForwardIt last, BinaryPredicate p );
adjacent_find
算法是用来寻找容器中第一对满足二元谓词关系p的相邻元素,如果找到了则会返回前一个元素的迭代器,若没有则会返回该容器的end( );- 当我们没有传递参数列表中的二元谓词时该算法默认判断相邻两元素是否相等,因为在该算法参数列表没有谓词的重载版本中就是判断相邻两个元素是否相当的;
binary_search 算法
定义:
template< class ForwardIt, class T, class Compare >
bool binary_search( ForwardIt first, ForwardIt last, const T& value, Compare comp );
- 该算法用于快速查找元素已经排序的容器在区间[first,last)之间是否存在元素value;
binary_search
算法的返回值为布尔类型,仅用于判断元素是否存在- 该算法与
find
算法的区别是该算法的时间复杂度更低,并且只能用于查找元素有序的容器binary_search
算法基于二分查找实现,时间复杂度为O(log n);
count 算法
声明:
template< class InputIt, class T >
typename std::iterator_traits<InputIt>::difference_typecount( InputIt first, InputIt last, const T& value );
- 该算法用于查找一个元素在容器中出现的次数;
typename std::iterator_traits<InputIt>::difference_type
为count函数的返回值类型,iterator_traits
是一个迭代器类模板用于提取传入迭代器InputIt
的各种属性,而difference_type
是该类中的一个成员属性 用来表示两个迭代器之间的距离;
为什么选择这个返回值类型:
- 第一 相同元素出现的次数可以理解为所有拥有相同元素迭代器放在一起,第一个迭代器和最后一个迭代器之间的距离
- 第二 该类型可表示的范围更大,防止使用int类型做返回值时会有溢出的风险;
count_if 算法
声明:
template< class InputIt, class UnaryPredicate >
typename std::iterator_traits<InputIt>::difference_typecount_if( InputIt first, InputIt last, UnaryPredicate p );
- 该算法用于查找容器中符合一元谓词p的条件的元素的数量,比count更加灵活;
常用排序算法
sort 算法
声明:
template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );
该算法用于给容器中的元素排序,排序的规则由二元谓词(仿函数)comp决定;
sort
算法也有不需要传递谓词参数的重载版本,默认为升序排序;
shuffle 算法
声明:
template< class RandomIt, class URBG >
void shuffle( RandomIt first, RandomIt last, URBG&& g);
shuffle
算法用于随机打乱指定范围的元素顺序;- 只有支持随机访问迭代器的容器才可以使用该算法;
- 该算法强制要求传入一个随机数生成引擎,保证了结果更可靠,并且可以复现;
- 该算法的旧版则不强制要求传入随机数生成引擎
旧版:
// 版本1:使用实现定义的随机源
template< class RandomIt >
void random_shuffle( RandomIt first, RandomIt last );// 版本2:使用自定义随机数生成器
template< class RandomIt, class RandomFunc >
void random_shuffle( RandomIt first, RandomIt last, RandomFunc&& r );
- 上述代码中版本一是使用编译器自带的随机数生成器,版本二则支持传入自定义的随机数生成器;
merge算法
声明:
template< class InputIt1, class InputIt2, class OutputIt, class Compare >
OutputIt merge( InputIt1 first1, InputIt1 last1,InputIt2 first2, InputIt2 last2,OutputIt d_first, Compare comp );
- 该算法用于合并两个元素已经排序的容器,并且两个容器排序的规则要一样,而且二元谓词comp的排序规则也要和它们相同;
- 也有不需要传入谓词或者仿函数的重载函数 其默认全部都是升序;
reverse算法
声明:
template< class BidirIt >
void reverse( BidirIt first, BidirIt last );
- 该算法用于翻转指定的容器;
常用拷贝和替换算法
replace_if 算法
声明:
template< class ForwardIt, class UnaryPredicate, class T >
void replace_if( ForwardIt first, ForwardIt last,UnaryPredicate p, const T& new_value );
- 该算法遍历容器中给定区间的元素,如果满足一元谓词p的条件则用new_value替换容器中原有的元素
replace 算法
声明:
template< class ForwardIt, class T >
void replace( ForwardIt first, ForwardIt last,const T& old_value, const T& new_value );
- 该算法用来将容器给定区间中所有值为
old_value
的元素替换为new_value
replace
算法替换的条件是固定的,但是replace_if
算法的替换条件可以通过自定义的一元谓词改变
copy 算法
声明:
template< class InputIt, class OutputIt >
OutputIt copy( InputIt first, InputIt last, OutputIt d_first );
- 该算法用于从目标容器的迭代器
d_first
开始,将另一个容器[first, last)之间的元素拷贝给自己- 该算法仅具有拷贝功能 要注意从
d_first
开始,容器的长度至少要等于拷贝区间的长度,否则会有越界访问的问题。
swap 算法
声明:
template< class T >
void swap( T& a, T& b );
- 使用
swap
算法时,不需要严格控制交换的两个容器的长度相等 因为swap
算法进行的交换不是简单的拷贝,容器的长度也会被交换
常用算术生成算法
accumulate算法
声明:
//默认版本
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );
//自定义版本
template< class InputIt, class T, class BinaryOperation >
T accumulate( InputIt first, InputIt last, T init, BinaryOperation op );
- 该算法的默认版本是将容器中的元素进行累加操作,返回的结果是累加的结果加上传入的
init
- 自定义版本可以传入函数指针或者仿函数进行其他累积操作,但是要注意传入的函数的返回值一定要让其支持链式操作
fill算法
声明:
template <class ForwardIt, class T>
void fill(ForwardIt first, ForwardIt last, const T& value);
该算法用于将
value
赋值给容器在 [first, last) 之间的元素;
常用集合算法
set_intersection 算法
声明:
template <class InputIt1, class InputIt2, class OutputIt>
OutputIt set_intersection(InputIt1 first1, InputIt1 last1,InputIt2 first2, InputIt2 last2,OutputIt d_first);
set_inttersection
算法用来求两个集合给定区间的交集,并将该交集的其实迭代器传给d_first
;
该函数的返回值将会返回交集的末尾迭代器;
set_union 算法
声明:
template <class InputIt1, class InputIt2, class OutputIt>
OutputIt set_union(InputIt1 first1, InputIt1 last1,InputIt2 first2, InputIt2 last2,OutputIt d_first);
set_union
算法用来求两个集合给定区间的并集;
并集的其实迭代器会传给d_first
,末尾迭代器则作为函数的返回值
set_difference 算法
声明:
template <class InputIt1, class InputIt2, class OutputIt>
OutputIt set_difference(InputIt1 first1, InputIt1 last1,InputIt2 first2, InputIt2 last2,OutputIt d_first);
该算法用来求前一个集合减去后一个集合的差集;
差集的起始迭代器会传给d_first
,而末尾迭代器会作为函数的返回值