STL中的算法

下表给出了STL中一些算法的名称、用途、是否质变和文件分布:

算法名称算法用途是否质变所在文件
accumulate元素累计<numeric>
adjacent_difference计算相邻元素的差值<numeric>
adjacent_find查找相邻而重复的元素<algorithm>
binarysearch二分查找<algorithm>
copy复制<algorithm>
copy_backward逆向复制<algorithm>
copy_n复制 n n n 个元素<algorithm>
count计数<algorithm>
count_if在特定条件下计数<algorithm>
equal判断两个区间是否相等<algorithm>
equal_range在有序区间中寻找某值<algorithm>
fill改填元素值<algorithm>
fill_n改填元素值 n n n<algorithm>
find循序查找<algorithm>
find_if循序查找符合特定条件的元素<algorithm>
find_end查找元素最后出现位置<algorithm>
find_first_of查找元素首次出现位置<algorithm>
for_each对区间的每个元素施行操作<algorithm>
generate将特定运算的结果填充到区间内<algorithm>
generate_n将特定运算的结果填充 n n n 个元素<algorithm>
includes检查元素是否包含于序列中<algorithm>
inner_product内积<numeric>
inplace_merge就地归并<algorithm>
iota在区间填入指定值的递增序列<numeric>
is_heap判断某区间是否为堆<algorithm>
is_sorted判断某区间是否已排序<algorithm>
iter_swap迭代器所指元素互换<algorithm>
lexicographical_cpmpare以字典序比较<algorithm>
lower_bound“将元素插入序列而不影响
区间原本排序”的最低位置
<algorithm>
max最大值<algorithm>
max_element最大值所在位置<algorithm>
merge归并两个序列<algorithm>
min最小值<algorithm>
min_element最小值所在位置<algorithm>
mismatch失配位置<algorithm>
next_permutation下一个排列组合<algorithm>
nth_element区间第 n n n<algorithm>
partial_sort局部排序<algorithm>
partial_sort_copy局部排序并复制到他处<algorithm>
partial_sum局部求和<numeric>
partition分割<algorithm>
prev_permutation前一个排列组合<algorithm>
power求幂次<numeric>
random_shuffle随机重排元素<algorithm>
random_sample随机取样<algorithm>
random_sample_n随机 n n n 次取样<algorithm>
remove删除某类元素<algorithm>
remove_copy删除某类元素并将结
果复制到另一个容器
<algorithm>
remove_if有条件地删除某类元素<algorithm>
remove_copy_if有条件地删除某类元素并
将结果复制到另一个容器
<algorithm>
replace替换某类元素<algorithm>
replace_copy替换某类元素并将结
果复制到另一个容器
<algorithm>
replace_if有条件地替换<algorithm>
replace_copy_if有条件地替换并将结
果复制到另一个容器
<algorithm>
reverse反转元素次序<algorithm>
reverse_copy反转元素次序并将结
果复制到另一个容器
<algorithm>
rotate旋转<algorithm>
rotate_copy旋转并将结果复
制到另一个容器
<algorithm>
search查找某个子序列<algorithm>
search_n查找连续发生
n n n 次的子序列
<algorithm>
set_difference差集<algorithm>
set_intersection交集<algorithm>
set_symmetric_difference对称差<algorithm>
set_union并集<algorithm>
sort排序<algorithm>
stable_partition稳定型分割<algorithm>
stable_sort稳定型排序<algorithm>
swap交换元素<algorithm>
swap_ranges交换指定区间<algorithm>
transform以两个序列为基础,交
互作用产生第三个序列
<algorithm>
unique去重<algorithm>
unique_copy去重并将结果复制到他处<algorithm>
upper_bound“将元素插入序列而不影响
区间原本排序”的最高位置
<algorithm>
make_heap制造堆<algorithm>
pop_heap从堆中取出一个元素<algorithm>
push_heap将元素放进堆中<algorithm>
sort_heap对堆进行排序<algorithm>

下面逐个介绍一些这些算法的用法。

STL算法的一般形式

所有泛型算法的前两个参数都是一对迭代器,通常称为 first \text{first} first last \text{last} last ,用以标示算法的操作区间。STL习惯采用前闭后开区间表示法,写成 [ first , last ) [\text{first},\text{last}) [first,last) 。这个区间必须满足的条件为,必须能经由累加(increment)操作符的反复运用,否则会导致无法预期的错误,且这个错误不一定在编译的时候被捕捉。

根据行进特性,迭代器分五种:Input Iterator、Output Iterator、Forward Iterator、Bidirectional Iterator、Random Access Iterator。这五种迭代器的逻辑层次见下图。每一个STL算法的声明都表现出它所需要的最低程度的迭代器类型。比如 find() 函数,它需要一个Input Iterator,但你给它传Forward Iterator或Bidirectional Iterator等都可以,就是不能传Output Iterator,否则会导致错误。同样,将无效的迭代器传给某个算法并不能保证在编译的时候能被捕捉,因此一定要小心使用。

Alt

许多STL算法不止支持一个版本。这一类的算法的某个版本采用缺省运算行为,另一个版本提供额外参数,接受外界传入一个仿函数,以便采用其他策略,这种函数一般会用"_if"结尾表示。

质变算法通常提供两个版本,就地的和复制到他处的,一般复制到他处的会以"_copy"结尾表示。当然并非所有质变算法都有copy版本,如 sort() 就没有。

所有的数值算法都实现于 <stl_numeric.h> 中,但这是内部文件,规定用户必须包含其上层的 <numeric> 。其他的算法实现于 <stl_algo.h><stl_algobase.h> 中,也都是内部文件,欲使用这些算法须包含上层头文件 <algorithm>

数值算法

这一部分的算法都包含在 <numeric> 头文件中。

accumulate

该算法用来计算区间 [ first , last ) [\text{first},\text{last}) [first,last) 内的元素和,使用时需要提供初始值 init ,算法返回和的值。

//版本一
template <class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T init);
//版本二
template <class InputIterator, class T, class BinaryOperation>
T accumulate(InputIterator first, InputIterator last, T init,
             BinaryOperation binary_op);

adjacent_difference

该算法用来计算区间 [ first , last ) [\text{first},\text{last}) [first,last) 中相邻元素的差值,需要传进一个 result 迭代器,算法将 *first 赋给 *result ,并针对 [ first + 1 , last ) [\text{first}+1,\text{last}) [first+1,last) 内的每个迭代器 i ,将 *i - *(i-1) 赋给 *(result + (i - first)) ,算法返回区间的尾端位置。

//版本一
template <class InputIterator, class OutputIterator>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
                                   OutputIterator result);
//版本二
template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator adjacent_difference(InputIterator first, InputIterator last,
                                   OutputIterator result,
                                   BinaryOperation binary_op);

inner_product

该算法可以计算 [ first1 , last1 ) [\text{first1},\text{last1}) [first1,last1) [ first2 , last2 ) [\text{first2},\text{last2}) [first2,last2) 的内积,需要提供初始值 init ,算法返回内积的值。

//版本一
template <class InputIterator1, class InputIterator2, class T>
T inner_product(InputIterator1 first1, InputIterator1 last1,
                InputIterator2 first2, T init);
//版本二
template <class InputIterator1, class InputIterator2, class T,
          class BinaryOperation1, class BinaryOperation2>
T inner_product(InputIterator1 first1, InputIterator1 last1,
                InputIterator2 first2, T init,
                BinaryOperation1 binary_op1,//加法
                BinaryOperation1 binary_op2);//乘法

partial_sum

该算法用来计算局部总和。它会将 *first 赋给 *result ,将 *first*(first + 1) 赋给 *(result + 1) ,依此类推,算法返回区间的尾端位置。

//版本一
template <class InputIterator, class OutputIterator>
OutputIterator partial_sum(InputIterator first, InputIterator last,
                           OutputIterator result);
//版本二
template <class InputIterator, class OutputIterator, class BinaryOperation>
OutputIterator partial_sum(InputIterator first, InputIterator last,
                           OutputIterator result, BinaryOperation binary_op);

power

这个算法由SGI专属,不在STL标准之列。它用来计算某个数的 n n n 幂次方,运算类型可由外界指定,但运算必须满足结合律(Monoid意味独异点)。算法返回幂次的值。

//版本一
template <class T, class Integer>
inline T power(T x, Integer n);
//版本二
template <class T, class Integer, class MonoidOperation>
T power(T x, Integer n, MonoidOperation op);

iota

这个算法由SGI专属,不在STL标准之列。它用来设定某个区间的内容,使其内的每一个元素从指定的 value 值开始,呈现递增状态,即,在区间 [ first , last ) [\text{first},\text{last}) [first,last) 内填入 valuevalue + 1value + 2 ,……。该算法无返回值。

template <class ForwardIterator, class T>
void iota(ForwardIterator first, ForwardIterator last, T value);

基本算法

在SGI中,一些常用的算法位于 <stl_algobase.h> 中,其他算法定义于 <syl_algo.h> 中,以下是定义在 <stl_algobase.h> 中的算法。

equal

如果两个序列在 [ first , last ) [\text{first},\text{last}) [first,last) 区间内相等,函数返回 true 。如果第二序列的元素比较多,多出来的元素不考虑。如果第二序列的元素比第一序列少,算法的内部迭代会超过序列的尾端,造成不可预测的结果。

//版本一
template <class InputIterator1, class InputIterator2>
inline bool equal(InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2);
//版本二
template <class InputIterator1, class InputIterator2,
          class BinaryPredicate>
inline bool equal(InputIterator1 first1, InputIterator1 last1,
                  InputIterator2 first2, BinaryPredicate binary_pred);

fill

该算法将 [ first , last ) [\text{first},\text{last}) [first,last) 内的所有元素改填新值。值得注意的是,该算法就是一个线性遍历赋值,所以能用 memset 就尽量不用 fill

template <class ForwardIterator, class T>
void fill(ForwardIterator first, ForwardIterator last, const T& value);

fill_n

该算法将 [ first , last ) [\text{first},\text{last}) [first,last) 内的前 n n n 个元素改填新值,返回被改填新值区间的尾端位置。须注意,若 n n n 超过了区间的长度将产生不可预期的结果。

template <class OutputIterator, class Size, class T>
OutputIterator fill_n(OutputIterator first, Size n, const T& value);

iter_swap

该算法将两个 Forward Iterator 所指的对象对调,两迭代器所指对象类型可以不同,用的是三变量交换法(这里就能看出traits技法的妙处了)。

template <class ForwardIterator1, class ForwardIterator2>
inline iter_swap(ForwardIterator1 a, ForwardIterator2 b);

lexicographical_compare

该算法以“字典排序方式”对两个序列 [ first1 , last1 ) [\text{first1},\text{last1}) [first1,last1) [ first2 , last2 ) [\text{first2},\text{last2}) [first2,last2) 进行比较。即,长度不同则短的比长的小,长度相同则第一个不同元素小的那个小。

//版本一
template <class InputIterator1, class InputIterator2>
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2);
//版本二
template <class InputIterator1, class InputIterator2, class Compare>
bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
                             InputIterator2 first2, InputIterator2 last2,
                             Compare comp);

此外,为了增进效率,SGI还设计了用于原生指针 const unsigned char*const char* 的特化版本,里面用到了 memcmp 函数。

max

取两个对象中的最大值。要求两个对象的类型必须一样。

//版本一
template <class T>
inline const T& max(const T& a, const T& b);
//版本二
template <class T, class Compare>
inline const T& max(const T& a, const T& b, Compare comp);

min

取两个对象中的最小值。要求两个对象的类型必须一样。

//版本一
template <class T>
inline const T& min(const T& a, const T& b);
//版本二
template <class T, class Compare>
inline const T& min(const T& a, const T& b, Compare comp);

mismatch

用来平行比较两个序列,指出两者之间的第一个不匹配点。返回一对迭代器,分别指向两序列中的不匹配点。算法要求第二序列的元素个数大于等于第一序列的。

//版本一
template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first,
                                              InputIterator1 last1,
                                              InputIterator2 first2);
//版本二
template <class InputIterator1, class InputIterator2,
          class BinaryPredicate>
pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first,
                                              InputIterator1 last1,
                                              InputIterator2 first2,
                                              BinaryPredicate binary_pred);

swap

该函数用来交换两个相同类型对象的内容,依然是三变量交换法。

template <class T>
inline void swap(T& a, T& b);

copy

该算法将输入区间 [ first , last ) [\text{first},\text{last}) [first,last) 内的元素复制到输出区间 [ result , result + ( last − first ) ) [\text{result},\text{result} + (\text{last} - \text{first})) [result,result+(lastfirst)) 内。算法并不是简单的遍历,它除了可以避免输入输出区间重叠而可能产生的错误(首先用了 memmove 把整个输入区间内容复制下来),也尽量进行了一些优化。

template <class InputIterator, class OutputIterator>
inline OutputIterator copy(InputIterator first, InputIterator last,
                           OutputIterator result);

copy_backward

copy 完成的事情相同,不过复制的顺序是相反的。即, copy 执行赋值操作 *result = *first*(result + 1) = *(first + 1) ,……,而 copy_backward 执行 *(result - 1) = *(last - 1)*(result - 2) = *(last - 2) ,……。

template <class BidirectionalIterator1, class BidirectionalIterator2>
inline BidirectionalIterator2 copy_backward(BidirectionalIterator1 first,
                                            BidirectionalIterator1 last,
                                            BidirectionalIterator2 result);




算了,算法太多写不完了,剩下的就对着表格看,然后百度查吧……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值