为了处理容器内的元素,STL提供了一些标准算法,包括搜寻、排序、拷贝、重新排序、修改、数值运算等,算法并非容器类别的成员函数,而是一种搭配迭代器使用的全局函数,这么做有一个优势:所有算法只需实作出一份,就可以对所有容器运作,不必为每一种容器量身定制。
STL算法采用覆盖模式而非安插模式,所以调用者必须保证目标区间有足够多的元素空间。
算法分类
不同的算法满足不同的需求,所以可以根据它们的主要目的加以分类,例如某些算法的操作是只读性的,某些算法会改动元素本身,某些则改动元素顺序。
- 非变动性算法
- 变动性算法
- 移除性算法
- 变序性算法
- 排序算法
- 已序区间算法
- 数值算法
非变动性算法既不改动元素次序,也不改动元素值。它们通过Input迭代器和Forward迭代器完成工作,因此可以作用于所有标准容器身上
for_each() | 对每个元素执行某操作 |
count() | 返回元素个数 |
count_if() | 返回满足某一条件的元素个数 |
min_element() | 返回最小值元素(以一个迭代器表示) |
max_element() | 返回最大值元素(以一个迭代器表示) |
find() | 寻找等于某值的第一个元素 |
find_if() | 寻找满足某条件的第一个元素 |
search_n() | 寻找具有某特性的第一段“n个连续元素” |
search() | 寻找某个子区间第一次出现位置 |
find_end() | 寻找某个子区间最后一次出现位置 |
find_first_of() | 寻找等于“某数个值之一”的第一个元素 |
adjacent_find() | 寻找连续两个相等的元素 |
equal() | 判断两区间是否相等 |
mismatch() | 返回两个序列的各组对应元素中,第一对不相等元素 |
lexicographical_compare() | 判断某一序列在“字典顺序”下是否小于另一序列 |
变动性算法要么直接改变元素值,要么在复制到另一区间的过程中改变元素值
for_each() | 对每一个元素执行某项操作 |
copy() | 从第一个元素开始,复制某段区间 |
copy_backward() | 从最后一个元素开始,复制某段区间 |
transform() | 变动(并复制)元素,将两个区间的元素合并 |
merge() | 合并两个区间 |
swap_ranges() | 交换两区间内的元素 |
fill() | 以给定值替换每一个元素 |
fill_n() | 以给定值替换n个元素 |
generate() | 以某项操作的结果替换每一个元素 |
generate_n() | 以某项操作的结果替换n个元素 |
replace() | 将具有某特定值的元素替换为另一个值 |
replace_if() | 将符合某标准的元素替换为另外一值 |
repalce_copy() | 复制整个区间,同时并将具有某特定值的元素替换为另一个值 |
replace_copy_if() | 复制整个区间,同时并将符合某准则的元素替换为另一个值 |
移除性算法是一种特殊的变动性算法。他们可以移除某区间内的元素,也可以在复制过程中执行移除动作
remove() | 将等于某值的元素全部移除 |
remove_if() | 将满足某准则的元素全部移除 |
remove_copy() | 将不等于某特定值的元素全部复制到它处 |
remove_copy_if() | 将不满足某准则的元素全部复制到它处 |
unique() | 移除相邻的重复元素 |
unique_copy() | 移除相邻的重复元素,并复制到它处 |
注意移除算法只是在逻辑上移除元素,手段是:将不需被移除的元素往前覆盖应被移除的元素。因此它并不改变操作区间内的元素个数,而是返回逻辑上的新终点位置。
变序性算法通过元素值的赋值和交换,改变元素顺序(但不改变元素的值)
reverse() | 将元素的次序逆转 |
reverse_copy() | 复制的同时,逆转元素顺序 |
rotate() | 旋转元素次序 |
rotate_copy() | 复制的同时,旋转元素次序 |
next_permutation() | 得到元素的下一个排列次序 |
prev_permutation() | 得到元素的上一个排列次序 |
random_shuffle() | 将元素的次序随机打乱 |
partition() | 改变元素次序,使“符合某准则”者移到前面 |
stable_partition() | 与partition()相似,但保持符合准则与不符合准则之间各个元素之间的相对位置 |
排序算法是一种特殊的变序性算法,但比一般的变序性算法复杂,花费更多时间
sort() | 对所有元素排序 |
stable_sort() | 对所有元素排序,并保持相等元素间的相对次序 |
partial_sort() | 排序,直到前n个元素就位 |
partial_sort_copy() | 排序,直到前n个元素就位,结果复制于它处 |
nth_element() | 根据第n个位置进行排序 |
partition() | 改变元素次序,使符合某准则的元素放在前面 |
stable_partition() | 与partition()相同,但保持符合准则和不符合准则的各个元素之间的相对位置 |
make_heap() | 将一个区间转换成一个heap |
push_heap() | 将元素加入一个heap |
pop_heap() | 从heap移除一个元素 |
sort_heap() | 对heap进行排序 |
已序区间算法 就是指其所作用的区间在某种排序准则下已序
binary_search() | 判断某区间是否包含某个元素 |
includes() | 判断某区间内的每一个元素是否都涵盖于另一区间中 |
lower_bound() | 搜寻第一个“大于等于给定值”的元素 |
upper_bound() | 搜寻第一个“大于给定值”的元素 |
equal_bound() | 返回“等于给定值”的所有元素构成的区间 |
merge() | 将两个区间的元素合并 |
set_union() | 求两个区间的并集 |
set_intersection() | 求两个区间的交集 |
set_difference() | 求位于第一区间但不位于第二区间的所有元素,形成一个已序区间 |
set_symmetric_difference() | 找出只出现于两区间之一的所有元素,形成一个已序区间 |
inplace_merge() | 将两个连续的已序区间合并 |
数值算法以不同的方式组合数值元素
accumulate() | 组合所有元素(求和、求积......) |
inner_product() | 组合两区间内的所有元素 |
adjacent_difference() | 将每个元素和其前一元素组合 |
partial_sum() | 将每个元素和其先前的所有元素组合 |
举一个简单的例子用一下算法
#include<vector>#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
vector<int> col;
vector<int>::iterator it;
//insert some elements
col.push_back(2);
col.push_back(5);
col.push_back(4);
col.push_back(1);
col.push_back(6);
col.push_back(3);
//find and print minimum and maximum elements
it=min_element(col.begin(),col.end());
cout<<"min: "<<*it<<endl;
it=max_element(col.begin(),col.end());
cout<<"max: "<<*it<<endl;
//sort all elements
sort(col.begin(),col.end());
//find the first element with value=3
it=find(col.begin(),col.end(),3);
//reverse the order of the found element with 3
reverse(it,col.end());
//print all elements
for(it=col.begin();it!=col.end();++it)
{
cout<<*it<<" ";
}
cout<<endl;
}
最终结果如下,不仅找到了最大值和最小值,而且将值为3的位置处到结尾处的元素逆序排列
上面提到的这些算法后面会逐一学习,展示它们的一些基本用法