不再造轮子,攻略 STL 中的所有算法
- STL 算法概观
- 数值算法
- 基本算法
- 3.1 equal, fill, fill_n, iter_swap, lexicographical_compare, max,min,mismatch, swap
- 3.2 copy --强化效率无所不用其极
- 3.3 copy_backward 反向拷贝
- 3.4 set 相关算法
- 3.4 heap 算法
- 3.5 单纯的数据处理算法
- adjacent_find : 找出满足条件的相邻元素
- count 与 count_if : 统计指定元素的个数
- find 和 find_if :查找第一个满足条件的元素
- find_end: 在序列1中查找序列2的最后一次出现点
- for_each : 遍历每一个元素,将仿函数 f 施加其每一个元素
- includes: s2 是否被包含于 s1 中
- max_element/min_element: 求序列中的最大/小元素
- merge 合并两个有序区间
- partition :分割排列元素,将满足特定条件的元素放在区间前半段
- remove 移除元素(但不是删除)
- replace : 将区间内的所有 old_value 全部用 new_value 取代
STL 算法概观
1.1 STL 算法总览
- 质变:指会改变其操作对象的内容
- *表示不在 STL 标准规格的 SGI 专属算法
- if in-place 指在同一区间操作




1.2 质变算法 mutating algorithm
STL 算法都作用在迭代器【first, last) 所标识的区间上。
质变算法: 在运算过程中会更改区间内(迭代器所指)的元素内容。
例如: 拷贝,交换,替换,填充,删除, 排列组合,分割, 随机重排,排序等算法,都属于该类。
若将该类算法运用到一个常数区间上,则编译器会给予一大堆错误 信息。
#include "main.h"
2 using std::vector;
3 int main()
4 {
5 vector<int> ivec{1,2,3,4,5};
6 sort(ivec.cbegin(), ivec.cend());
7 return 0;
8 }
9

1.3 非质变算法 nomutating algorithms
非质变算法: 在运算过程中不会改变区间内元素的内容
诸如: 查找,匹配,计数,遍历,比较等算法
如果在这些算法添加一个会改变内容的仿函数, 元素当然会被改变。
1.4 STL 算法的一般形式
- 所有泛型算法的前两个参数都为一对迭代器,且位前闭后开区间【first, last)
- 区间必须满足first 累加操作的反复运用,能到达 last,因此需要保证算法能接收的最低程度的迭代器类型。
- 设置特定操作: STL 算法中大多支持多个版本,拥有自己的缺省行为, 通过外界传递仿函数(functor),以便采用其他策略。 附从 _if 的算法如 find_if 也是一样可以传递仿函数进行对比行为。
- 具有拷贝版本的算法: 在质变算法中,除了就地修改外,还提供了 copy(另行版本)将修改后的区间序列拷贝到另外的地方,如: replace_copy
数值算法都实现与 numeric 中,其他都实现在 algorithm 中
数值算法
数值算法统一定义在 numeric 中, 我们来介绍如下几种:
int ia[5] = {1, 2, 3, 4, 5};
6 vector<int> iv(ia, ia+5);
7 cout << accumulate(iv.begin(), iv.end(), 0) << endl;
// 15
8 cout << accumulate(iv.begin(), iv.end(), 0, minus<int>()) << endl;
// -13
9 cout << inner_product(iv.begin(), iv.end(), iv.begin(),10) << endl;
// 10 + 1*1 + 2*2 .。。。
10 cout << inner_product(iv.begin(), iv.end(), iv.begin(), 10, minus<int>(), plus<int>());
// 10 - (1+1) - (2+2) -(3+3)
11
12 ostream_iterator<int> oite(cout, " ");
13 partial_sum(iv.begin(), iv.end(), oite) ;
// 1 3 6 10 15
14 partial_sum(iv.begin(), iv.end(), oite, minus<int>());
15 // 1 -1 - 4 -8 -13
16 adjacent_difference(iv.begin(), iv.end(), oite);
// 1 1 1 1 1
17 adjacent_difference(iv.begin(), iv.end(), oite, plus<int>());
18 // 1 3 5 7 9
2.1 accumulate 元素累计算法
- 将元素按二元仿函数的规则累计操作的结果相加到 init 上。
- 默认是 1+2+3 ,若位 minus则, 1-2-3.。。
1 // 版本1
2 template <class InputIterator, class T>
3 T accumulate(InputIterator first, InputIterator last, T init) {
4 for(; first != last; ++first)
5 init += *first;
6 return init;
7 }
8 //版本2
9 template <class InputIterator, class T, class BinaryOperation>
10 T accumulate(InputIterator first, InputIterator last, T init,
11 BinaryOperation binary_op) {
12 for(; first != last; ++first)
13 init = binary_op(init, *first);
14 return init;
15 }
2.2 adjacent_difference 相邻元素之间的差额算法
- 用于计算 【first, last)中相邻元素的差额。
- 将 *first 赋值给 *result ,并针对 [first+1,last) 内的每个迭代器 i, 将 *i - *(i-1)的值赋值给 *(result + (i - first))
- 提供二元仿函数的版本是 将 binary_op(*i, *(i-1)) 的运算结果赋值给 *(result+i-first)
18 template <class InputIterator, class OutputIterator>
19 OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result) {
20 if(first == last)
21 return result;
22 *result = *first;
23 typedef typename std::iterator_traits<InputIterator>::value_type value_type;
24 value_type value = *first;
25 while(++first != last) {
26 value_type tmp = *first; //原地操作时会造成问题,因此需要临时量
27 *++result = tmp - value;
28 value = tmp;
29 }
30 return ++result;
31 }
32 template <class InputIterator, class OutputIterator, class BinaryOperation>
33 OutputIterator adjacent_difference(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op) {
34 if(first == last)
35 return result;
36 *result = *first;
37 using value_type = typename std::iterator_traits<InputIterator>::value_type;
38 value_type val = *first;
39 while(++first != last) {
40 value_type tmp = *first;
41 *++result = tmp - val;
42 val = tmp;
43 }
44 return ++result;
45 }
2.3 inner_product 求两个区间的一般内积(对应元素相乘之后累加一起)
- 算法 inner_product 能够计算 【first1, last1) 和 【first2, first2+ (last1 - first1))的一般内积,
先将初始结果初始化位 init, 之后针对 【first1 , last1)的每一个迭代器 i, 从头至尾依序执行
result = result + (*i) * *(first2 + (i - first1))
- 需要提供初始值 init ,为了能在两个区间都为空的情况下有一个明确的值
- 可提供仿函数取代 operator+ 和 operator*,
先将初始结果初始化为 init, 之后针对【first1, last1) 的每一个迭代器i, 从头到尾依序执行:
result = bindary_op1(result, bindary_op2(*i, *(first2 +(i-first1))))
47 template<class InputIterator1, class InputIterator2, class T>
48 T inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init) {
49 for(; first1 != last1; ++first1, ++first2) {
50 init += *first1 * *first2;
51 }
52 return init;
53 }
54
55 template<class InputIterator1,class InputIterator2, class T,
56 class BinaryOperation1, class BinaryOperation2>
57 T inner_product(InputIterator1 first1, InputIterator1 last1,InputIterator2 first2, T init,
58 BinaryOperation1 binary_op1, BinaryOperation2 binary_op2) {
59 for(; first1 != last1; ++first1, ++first2) {
60 init = binary_op1(init, binary_op2(first1, first2));
61 }
62 return init;
63 }
64
2.4 partial_sum 计算局部总和
- 运算中的局部总和 sum 首先初始化为 *first, 然后赋值给 *result, 之后随着first 的遍历sum = sum + *first, 之后赋值给 *(result + i - first)
- 带 二元仿函数的即 sum = binary_op(sum, *first)
65 template<class InputIterator, class OutputIterator>
66 OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result) {
67 if(first == last)
68 return result;
69 using value_type = typename std::iterator_traits<InputIterator>::value_type;
70 value_type sum = *first;
71 while(++first != last) {
72 sum += *first;
73 *++result = sum;
74 }
75 return ++result;
76 }
77 template<class InputIterator, class OutputIterator, class BinaryOperation>
78 OutputIterator partial_sum(InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op) {
79 if(first == last)
80 return result;
81 using value_type = typename std::iterator_traits<InputIterator>::value_type;
82 value_type sum = *first;
83 while(++first != last) {
84 sum = binary_op(sum, *first);
85 *++result = sum;
86 }
87 return ++result;
88 }
2.5 power
该算法不再标准之内,用来计算 某个数的 n 幂次方,可以指定其数的某种运算
x的n次方 = x 的 n/2 次方 * x 的n/2次方 。(n 为奇数须再次乘上 x)
template <class T, class Integer, class MonoidOperation>
92 T power(T x, Integer n, MonoidOperation op) {
93 if(n == 0)
94 return 1;
95 else {
96 while((n & 0x1) == 0) {
97 n >>= 1;
98 x = op(x, x);
99 }
100 T result = x;
101 n >>= 1;
102 while(n != 0) {
103 x = op(x, x);
104 if((n & 0x1) != 0)
105 result = op(result, x);
106 n >>= 1;
107 }
108 return result;
109 }
110 }
111 template <class T, class Integer>
112 inline T power(T x, Integer n) {
113 return power(x, n, std::multiplies<T>());
114 }
基本算法
STL 标准中并没有区分基本算法和复杂算法,然而 SGI 却将常用的一些算法定义于 <stl_algobase.h>中,其他算法定义在 <stl_algo.h>
3.1 equal, fill, fill_n, iter_swap, lexicographical_compare, max,min,mismatch, swap
这一小节列出定义于 <stl_algobase.h>头文件中的所有算法, copy 与 copy_backward() 算法除外, 因为这两个函数复杂许多, 在效率方面有诸多考虑, 我们把他们安排在另外的小节。
equal: 序列相等性判断
- 两个序列在 【first, last)区间内相等,equal 返回 true。
- 如果序列的元素不均等,多出的元素不予考虑,如果第二序列元素少于第一序列, 则在遍历时很可能会越界访问造成错误。
因此,如果我们希望保证两个序列完全相等, 必须先判断其元素个数是否相等。
第一个版本,默认使用 equality 操作符,例如 vec1 == vec2
第二个版本,允许指定其谓词
1 template <class InputIterator1, class InputIterator2>
2 inline bool equal(InputIterator1 first1, InputIterator1 last1,
3 InputIterator2 first2) {
4 for(; first1 != last1; ++first1, ++first2) {
5 if(*first1 != *first2)
6 return false;
7 }
8 return true;
9 }
10
11 template <class InputIterator1, class InputIterator2, class BindaryPredicate>
12 inline bool equal(InputIterator1 first1, InputIterator1 last1,
13 InputIterator2 first2, BindaryPredicate bindary_pred) {
14 for(; first1 != last1; ++first1, ++first2) {
15 if(!bindary_pred(*first1, *first2) ) {
16 return false;
17 }
18 return true;
19 }
20 }
21
fill: 序列填充value
将 【first, last) 内的元素全部改填新值
22 template <class ForwardIterator, class T>
23 void fill(ForwardIterator first, ForwardIterator last, const T &value) {
24 for(; first != last; ++first)
25 *first = value;
26 }
27
fill_n
将 【first, last)年内的前 n 个元素该填写新值,返回的迭代器指向被填写的最后一个元素的下一位置
28 template <class OutputIterator, class Size, class T>
✹ 29 OutputIterator fill_n(OutputIterator first, Size n, const T &value) {
30 for(; n > 0; --n, ++first)
31 *first = value;
32 return first;
33 }
34
35
如果 n 超越了容器的现有大小, 则会造成不可预知的后果
iterator_swap: 迭代器的交换
将两个 ForwardIterators 所指的对象对调。
36 template <class ForwardIterator1, class ForwardIterator2>
37 inline void iter_swap(ForwardIterator1 a, ForwardIterator2 b) {
38 using value_type = typename std::iterator_traits<ForwardIterator1>::value_type;
39 value_type tmp_val = *a;
40 *a = *b;
41 *b = tmp_val;
42 }
lexicographical_compare: 判断两个序列的字典序大小
以“字典排列方式” 对两个序列【first1, last1) 和 【first2,last2)进行比较, 比较操作针对两序列中的对应位置上的元素进行,并持续直到
(1)某一组对应元素彼此不相等;
(2)同时到达 last1 和 last2 (当两序列的大小相同);
(3) 到达 last1 或 last2(当两序列的大小不同)
当这个函数在对应位置上发现第一组不相等的元素时, 有下列几种可能:
- 如果第一序列的元素较小, 返回true, 否则返回 false
- 如果到达 last1而尚未达到 last2,返回 true
- 如果到达 last 2 而尚未达到 last, 返回 false
- 如果同时到达 last1 和 last2 (换句话说所有元素都匹配), 返回 false;第一序列以字典排列方式而言不小于第二序列。
- 第一版本以小于号进行比较
- 第二版本以自定义比较谓词进行比较
44 template <class InputIterator1, class InputIterator2>
45 bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
46 InputIterator2 first2, InputIterator2 last2) {
47 //若一方到达尾端就结束,否则就一一对比
48 for(; first1 != last1 && first2 != last2; ++first1, ++first2) {
49 if(*first1 < *first2)
50 return true;
51 if(*first2 < *first1)
52 return false;
53 }
54
55 return first1 == last1 && first2 != last2;
56 }
57 template <class InputIterator1, class InputIterator2, class Compare>
58 bool lexicographical_compare(InputIterator1 first1, InputIterator1 last1,
✹ 59 InputIterator2 first2, InputIterator2 last2, Compare comp) {
60 for(; first1 != last1 && first2 != last2; ++first1, ++first2) {
61 if(comp(*first1, *first2))
62 return true;
63 if(comp(*first1, *first2))
64 return false;
65 }
66
67 return first1 == last1 && first2 != last2;
68 }
69
70
为了增进效率, SGI 设计了一个特例化版本, 用于原生指针 const unsigned char *;
采用的是 memcmp 原生的C标准库函数,比较其每一个字节
inline bool lexicographical_compare(
const unsigned char *first1,
const unsigned char *last1,
const unsigned char *first2,
const unsigned char *last2
)
{
const size_t len1 = last1 - first1;
const size_t len2 = last2 - first2;
const int result = memcmp(first1, first2, std::min(len1, len2));
return result != 0 ? result < 0 : len1 < len2;
}
max:取最大值
取两个对象中的最大值,一个版本使用 greate-than 操作符判断大小,一个使用 仿函数 compare 来判断大小;
template <class T>
inline const T& max(const T &a, const T &b) {
return a < b ? b : a;
}
template <class T, class Compare>
inline const T &max(const T &a, const T &b, Compare comp) {
return comp(a,b) ? b : a;
}
min:取最小值
取两个对象中的最小值,一个版本使用 less-than 操作符判断大小,一个使用 仿函数 compare 来判断大小;
template <class T>
inline const T& min(const T &a, const T &b) {
return a < b ? a : b;
}
template <class T, class Compare>
inline const T &min(const T &a, const T &b, Compare comp) {
return comp(a,b) ? a : b;
}
mismatch: 找出不匹配点
用于平行比较两个序列, 指出两者之间的第一个不匹配点,返回一对迭代器,分别指向两序列中的不匹配点。
- 如果两个序列所有对应元素都匹配,返回则是两序列各自的last迭代器
- 缺省情况下是用 equality 操作符来比较元素,第二版本允许用户指定其比较操作
- 如果第二序列比第一个序列元素多,多出元素忽略不计,如果第二序列的元素个数比第一序列少,会发生未可预期的行为。
template <class InputIterator1, class InputIterator2>
pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator last1,
InputIterator1 first2) {
while(first1 != last1 && *first1 == *first2) {
++first1;
++first2;
}
return pair<InputIterator1, InputIterator2>(first1, first2);
}
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator last1,
InputIterator1 first2, BinaryPredicate binary_pred) {
while(first1 != last1 && binary_pred(*first1, *first2)) {
++first1;
++first2;
}
return pair<InputIterator1, InputIterator2>(first1, first2);
}
swap:交互
交互两个对象的内容
template <class T>
inline void swap(T &a, T &b) {
T tmp = a;
a = b;
b = tmp;
}
3.2 copy --强化效率无所不用其极
不同的传参决定不同的 copy 版本
正常版本的使用:
传入迭代器
*(result) = *first
*(result + 1) = *(first + 1) //向前推进
特例化的版本:
传入字符指针,const char *
使用 memmove()
COPY的区间重叠问题
- 当 result 的终点 result + (last-first) 在 区间 [first , last) 中,则无影响。
- 当result 在 区间 [first, last) 中,则会可能出错
如果迭代器为原生指针(RandomIterator)的话,不会出错,因为使用的是 memmove 操作,memmove是会预报留输入区间,因此没有覆盖的危险。
copy(first,last, result);
返回值为拷贝的末尾
3.3 copy_backward 反向拷贝
倒叙拷贝
3.4 set 相关算法
set_union: 构建两个集合并集
set_union 可构建 S1,S2的并集, 此集合内含 S1 或 S2 内的每一个元素。
- S1, S2 及其并集都是以排序区间表示
- 返回为一个迭代器,指向输出区间的尾部
若一个元素在 S1 出现 n 次, S2 出现 m 次,那么该值在输出区间内会出现 max(m,n )次,其中 n个来自 s1,其余来自 s2
其他特点: 稳定排序,第一版本是 operator< 比较,第二版本使用仿函数 comp 进行比较
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_union(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result) {
while (first1 != last1 && first2 != last2) {
if(*first1 < *first2) {
*result = *first1;
++first1;
} else if(*first2 < *first1) {
*result = *first2;
++first2;
} else {
*result = *first1;
++first1;
++first2;
}
++result;
}
return std::copy(first2, last2, std::copy(first1, last1, result));
}
set_intersection: 构建两个集合交集
算法set_intersection可构建 s1, s2交集, 此集合内含同时出现于 s1 和 s2 内的每一个元素。
- s1,s2 及其交集以排序区间表示
- 返回一个迭代器,指向输出区间的尾端。
- 如果一个元素在两个区间内各有 m,n 则最终输出区间中会出现 min(m, n) 次
- 稳定的(stable) ,且第一版本使用 operator< 比较,第二版本采用仿函数 comp 进行比较
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_intersection(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result) {
while(first1 != last1 && first2 != last2) {
if(*first1 < *first2) {
++first1;
} else if(*first2 < *first1)
++first2;
else {
*result = *first1;
++first1;
++first2;
++result;
}
}
return result;
}
set_difference:构建两个集合差集
算法set_difference 可构造 s1, s2 差集, s1-s2 “出现于s1 但不出现于 s2 ”的每一个元素。
- s1, s2 及其交集都是以排序区间表示
- 返回值为一个迭代器,指向输出区间的尾部
- 如果一个元素在 s1出现 m 次, s2 出现 n 次,那么该值在输出区间出现 max((m-n), 0) 次
- 稳定操作,第一版本使用 operator< 比较, 第二版本使用 仿函数 comp 比较
template <class InputIteraotr1, class InputIteraotr2, class OutputIterator>
OutputIterator set_difference(InputIteraotr1 first1, InputIteraotr1 last1,
InputIteraotr2 first2, InputIteraotr2 last2,
OutputIterator result) {
//当两个区间都未达到尾端时,执行如下操作
while(first1 != last1 && first2 != last2) {
if(*first1 < *first2) {
*result = *first1;
++result;
} else if(*first2 < *first1) {
++first2;
} else {
++first1;
++first2;
}
}
return std::copy(first1, last1, result);
}
set_symmetric_difference:构建两个集合对称差集
求 S1, S2 的对称差集 ( S1-S2)U (S2-S1)
包含:出现在 S1但不出现 S2 以及 出现 S2 但不出现在S1的每一个元素
- s1,s2 都为排序区间
- 返回值为一个迭代器,指向输出区间的尾端
- 当 s1 和 s2 内的每个元素都不需唯一, 因此当某个值在 s1中出现n次,在 s2 出现 m 次,那么该值在输出区间会出现 |n-m|次。
- 稳定操作,第一版本使用 operator< 进行比较, 第二版本采用仿函数 comp
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator set_syymmetric_difference(InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
InputIterator2 last2,
OutputIterator result) {
while(first1 != last1 && first2 != last2) {
if(*first1 < *first2) {
*result = *first1;
++first1;
++result;
} else if(*first2 < *first1) {
++result = *first2;
++first2;
++result;
} else {
++first1;
++first2;
}
}
return std::copy(first2, last2, std::copy(first1,last1, result));
}
3.4 heap 算法
vector<int> ivec;
make_heap(ivec.begin(), ivec.end(), greater<int>());
ivec.push_back(1);
push_heap(ivec.begin(), ivec.end(), greater<int>());
pop_heap(ivec.begin(), ivec.end());
ivec.pop_back();
sort_heap(ivec.begin(), ivec.end(), greater<int>());
3.5 单纯的数据处理算法
adjacent_find : 找出满足条件的相邻元素
默认找两元素相等, 另外一个版本可以通过写出二元运算来执行算法
- 返回相邻元素相等的起点的迭代器,未找到返回 last
template <class ForwardIterator>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) {
if(first == last)
return last;
ForwardIterator next = first;
while(++next != last) {
if(*first == *next)
return first;
first = next;
}
return last;
}
template <class ForwardIterator, class BinaryPredicate>
ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last,
BinaryPredicate binary_predicate) {
if(first == last)
return last;
ForwardIterator next = first;
while(++next != last) {
if(binary_predicate(*first, *next))
return first;
first = next;
}
return last;
}
count 与 count_if : 统计指定元素的个数
- 运用 operator= 操作符,将区间【first, last) 区间内的每一个元素拿来和指定值 value 比较,返回与 value相等的元素个数。
template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last, const T &value) {
typename iterator_traits<InputIterator>::difference_type n = 0;
for(; first != last; ++first) {
if(*first == value)
++n;
}
return n;
}
template <class InputIterator, class Predicate>
typename iterator_traits<InputIterator>::difference_type
count_if(InputIterator first, InputIterator last, Predicate pred) {
typename iterator_traits<InputIterator>::difference_type n = 0;
for(; first != last; ++first) {
if(pred(*first))
++n;
}
return n;
}
find 和 find_if :查找第一个满足条件的元素
- 默认采用 operator= 来循序查找区间内符合等同的元素, find_if 提供了仿函数,令仿函数运算结果为 true的元素即符合条件
- 返回为找到的元素的迭代器, 否则返回 迭代器 last
template <class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last,
const T &value) {
while(first != last && *first != value)
++first;
return first;
}
template <class InputIterator, class Predicate>
InputIterator find_if(InputIterator first, InputIterator last,
Predicate pred) {
while(first != last && !(pred(*first)))
++first;
return first;
}
find_end: 在序列1中查找序列2的最后一次出现点
template<class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1
find_end(ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2);
for_each : 遍历每一个元素,将仿函数 f 施加其每一个元素
- 只读算法, 迭代器为 inputiterator, 如果修改应该使用 transform
template <class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f) {
for(; first != last; ++first)
f(*first);
return f;
}
includes: s2 是否被包含于 s1 中
- s1 s2 均为有序区间
- include 算法可供用户选择 less 或 greater 进行两元素的大小比较
使用:
includes(s1.begin(), s1.end(), s2.begin(), s2.end());
includes(s1.begin(), s1.end(), s2.begin(), s2.end(), greater<int>());
template <class InputIterator1, class InputIterator2>
bool includes(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2) {
while(first1 != last1 && first2 != last2) {
if(*first2 < *first1)
return false;
else if(*first1 < *first2)
++first1;
else
++first1, ++first2;
}
return first2 == last2;
}
max_element/min_element: 求序列中的最大/小元素
template <class ForwardIterator>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last) {
if(first == last)
return first;
ForwardIterator result = first;
while(++first != last)
if(*result < *first)
result = first;
return result;
}
template <class ForwardIterator, class Compare>
ForwardIterator max_element(ForwardIterator first, ForwardIterator last,
Compare comp) {
if(first == last)
return first;
ForwardIterator result = first;
while(++first != last)
if(comp(*result, *first))
result = first;
return result;
}
merge 合并两个有序区间
- 排序后的 S1 和 S2
- 返回为合并后的序列的末尾
template <class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator merge(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2,
OutputIterator result) {
while(first1 != last1 && first2 != last2) {
if(*first2 < *first1) {
*result = *first2;
++first2;
}
else {
*result = *first1;
++first1;
}
++result;
}
return std::copy(first2, last2, std::copy(first1, last1, result));
}
partition :分割排列元素,将满足特定条件的元素放在区间前半段
- 对于 仿函数判定为 true 的元素放于区间的前段, 判定为 false 的元素放于区间的后半段。
- 非稳定性分割,如果需要稳定使用 stable_partition
template <class BidirectionalIterator, class Predicate>
BidirectionalIterator partition(BidirectionalIterator first,
BidirectionalIterator last,
Predicate pred) {
while(true) {
while(true)
if(first == last)
return first;
else if(pred(*first))
++first;
else
break;
--last;
while(true)
if(first == last)
return first;
else if(!pred(*last))
--last;
else
break;
iter_swap(first, last);
++first;
}
}
remove 移除元素(但不是删除)
- 移除区间内所有与 value 相等的元素, 并不是真正从容器中删除那些元素, 而是将每一个不与 value 相等的元素轮番赋值给 first 之后的空间。
- 对于array,更喜欢的是 remove_copy 和 remove_copy_if 版本
- 返回删除后的数组的末尾元素的下一个位置。
template <class InputIterator, class OutputIterator, class T>
OutputIterator remove_copy(InputIterator first, InputIterator last,
OutputIterator result, const T &value) {
for(; first != last; ++first) {
if(*first != value) {
*result = *first;
++result;
}
}
return result;
}
template <class InputIterator, class OutputIterator, class Predicate>
OutputIterator remove_copy_if(InputIterator first, InputIterator last,
OutputIterator result, Predicate pred) {
for(; first != last; ++first) {
if(!pred(*first)) {
*result = *first;
++result;
}
}
return result;
}
template <class ForwardIterator, class T>
ForwardIterator remove(ForwardIterator first, ForwardIterator last,
const T &value) {
first = find(first, last, value);
ForwardIterator next = first;
return first == last ? first : remove_copy(++next, last, first, value);
}
template <class ForwardIterator, class Predicate>
ForwardIterator remove_if(ForwardIterator first, ForwardIterator last,
Predicate pred) {
first = find_if(first, last, pred);
ForwardIterator next = first;
return first == last ? first : remove_copy_if(++next, last, first, pred);
}
replace : 将区间内的所有 old_value 全部用 new_value 取代
template <class ForWardIterator, class T>
void replace(ForWardIterator first, ForWardIterator last,
const T &old_val, const T &new_val) {
for(; first != last; ++first)
if(*first == old_val)
*first = new_val;
}
template <class ForWardIterator, class OutputIterator, class T>
void replace_copy(ForWardIterator first, ForWardIterator last,
OutputIterator result,
const T &old_val, const T &new_val) {
for(; first != last; ++first)
if(*first == old_val)
*first = new_val;
}
template <class ForwardIterator, class Predicate, class T>
void replace_if(ForwardIterator first, ForwardIterator last,
Predicate pred, const T &new_val) {
for(; first != last; ++first)
if(pred(*first))
*first = new_val;
}
template <class Iterator, class OutputIterator, class Predicate, class T>
OutputIterator replace_copy_if(Iterator first, Iterator last,
OutputIterator result, Predicate pred,
const T &new_value) {
for(; first != last; ++first, ++result) {
*result = pred(*first) ? new_value : *first;
}
return result;
}

491

被折叠的 条评论
为什么被折叠?



