修改序列的操作
定义于头文件 <algorithm>
transform
定义
1 | template< class InputIt, class OutputIt, class UnaryOperation > |
功能
std::transform
应用给定的函数到范围并存储结果于始于 d_first
的另一范围。
应用一元函数 unary_op
到 [first1, last1)
所定义的范围。
参数
first1
,last1
- 要变换的第一元素范围d_first
- 目标范围的起始,可以等于first1
或first2
unary_op
- 将要应用的一元算符函数。
函数签名应等价于如下者:
1 | Ret fun(const Type &a); |
签名不必有 const &
。
类型 Type
必须使得 InputIt
类型对象能在解引用后隐式转换到 Type
。 类型 Ret
必须使得 OutputIt
类型对象能被解引用并能被赋 Ret
类型值。
返回值
指向最后一个变换的元素的输出迭代器。
复杂度
准确应用 std::distance(first1, last1)
次 unary_op
。
示例
记得::tolower
前面有::
, 而且是::tolower
,不是::tolower()
1 |
|
swap
定义
1 | template< class T > |
功能
交换给定值
1)交换 a
与 b
。
2)交换 a
与 b
数组。等效于调用 std::swap_ranges(a, a+N, b)
。
参数
a
,b
- 要交换的值
复杂度
1) 常量
2) 与 N
成线性
示例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
int a = 5, b = 3;
// 前
std::cout << a << ' ' << b << '\n';
std::swap(a,b);
// 后
std::cout << a << ' ' << b << '\n';
}
输出1
25 3
3 5
swap_ranges
1 | template< class ForwardIt1, class ForwardIt2 > |
功能在范围 [first1, last1)
和始于 first2
的另一范围间交换元素。
参数
first1
,last1
- 要交换的第一个元素范围first2
- 要交换的第二个元素范围的起始
返回值
指向始于 first2
的范围中被交换的最末元素后一元素的迭代器。
可能的实现
1 | template<class ForwardIt1, class ForwardIt2> |
复杂度
与 first1
和 last1
的距离成线性
示例
演示来自不同容器的子范围交换
1 |
|
输出
1 | -1 -2 -3 4 5 |
iter_swap
定义
1 | template< class ForwardIt1, class ForwardIt2 > |
参数
a
,b
- 指向要交换的元素的迭代器
复杂度
常数
可能的实现
1 | template<class ForwardIt1, class ForwardIt2> |
示例
下面是选择排序在 C++ 中的实现
1 |
|
输出
1 | Before sort: -7 6 2 4 -1 6 -9 -1 2 -5 10 -9 -5 -3 -5 -3 6 6 1 8 |
reverse
定义
1 | template< class BidirIt > |
功能
反转 [first, last)
范围中的元素顺序
参数
first
,last
- 要反转的元素的范围
可能的实现
1 | template<class BidirIt> |
复杂度
和 first
与 last
间的距离成线性
示例
1 |
|
输出
1 | 321 |
reverse_copy
定义
1 | template< class BidirIt, class OutputIt > |
功能
复制来自范围 [first, last)
的元素到始于 d_first
的新范围,使得新范围中元素以逆序排列。
参数
first
,last
- 要复制的元素范围d_first
- 新范围的起始
返回值
指向最后被复制元素后一元素的迭代器。
可能的实现
1 | template<class BidirIt, class OutputIt> |
复杂度
与 first
和 last
间的距离成线性。
示例
1 |
|
输出
1 | 1 2 3 |
排序操作
定义于头文件 <algorithm>
sort
定义
1 | template< class RandomIt > |
功能
以升序排序范围 [first, last) 中的元素。不保证维持相等元素的顺序。
- 1) 用 operator< 比较元素。
- 2) 用给定的二元比较函数 comp 比较元素。
参数
first
,last
- 要排序的元素范围policy
- 所用的执行策略。细节见执行策略。comp
- 比较函数对象(即满足比较 (Compare) 概念的对象),若第一参数小于(即先序于)第二参数则返回true
。
比较函数的签名应等价于如下:
1 | bool cmp(const Type1 &a, const Type2 &b); |
虽然签名不必有 const &
,函数也不能修改传递给它的对象,而且必须接受(可为 const
的)类型 Type1
与 Type2
的值,无关乎值类别(从而不允许 Type1 &
,亦不允许 Type1
,除非 Type1
的移动等价于复制 (C++11 起))。
类型 Type1
与 Type2
必须使得 RandomIt
类型的对象能在解引用后隐式转换到这两个类型。
复杂度
- 平均
O(N·log(N))
次比较,其中N = std::distance(first, last)
。(C++11 前) O(N·log(N))
次比较,其中N = std::distance(first, last)
。(C++11 起)
示例
1 |
|
输出
1 | 0 1 2 3 4 5 6 7 8 9 |
最小/最大操作
定义于头文件 <algorithm>
max
定义
1 | template< class T > |
功能
返回给定值中的较大者。
- 1-2) 返回
a
与b
的较大者。 - 3-4) 返回
initializer_list ilist
中值的最大者。 - (1,3) 版本用
operator<
比较元素, (2,4) 版本用给定的比较函数comp
。
参数
a
,b
- 要比较的值ilist
- 拥有要比较的值的initializer_list
cmp
- 比较函数对象(即满足比较 (Compare) 要求的对象),若若a
小于b
,则返回 true
。
比较函数的签名应等价于如下:
1 | bool cmp(const Type1 &a, const Type2 &b); |
虽然签名不必有 const &
,函数也不能修改传递给它的对象,而且必须接受(可为 const
的)类型 Type1
与 Type2
的值,无关乎值类别(从而不允许 Type1 &
,亦不允许 Type1
,除非 Type1
的移动等价于复制 (C++11 起))。
类型 Type1
与 Type2
必须使得 T 类型的对象能隐式转换到这两个类型。
返回值
- 1-2)
a
与b
的较大者。若它们等价,则返回a
。 - 3-4)
ilist
中的最大值。若有数个等价于最大者的值,则返回最左侧的这种值。
复杂度
- 1-2) 准确一次比较
- 3-4) 准确
ilist.size() - 1
次比较
可能的实现
版本一
1 | template<class T> |
版本二
1 | template<class T, class Compare> |
版本三
1 | template< class T > |
版本四
1 | template< class T, class Compare > |
注意
若参数之一是右值,且返回该参数,则以引用捕获 std::max
的结果会产生一个悬垂引用:
1 | int n = 1; |
示例
1 |
|
输出
1 | larger of 1 and 9999: 9999 |
max_element
定义1
2
3
4
5template< class ForwardIt >
ForwardIt max_element(ForwardIt first, ForwardIt last );
template< class ForwardIt, class Compare >
ForwardIt max_element(ForwardIt first, ForwardIt last, Compare comp );
功能
寻找范围 [first, last)
中的最大元素。
1) 用 operator<
比较元素。
2) 用给定的二元比较函数 comp
比较元素。
参数
first
,last
- 定义要检验范围的向前迭代器comp
- 比较函数对象(即满足比较 (Compare) 要求的对象),若首个参数小于第二个,则返回true
。
比较函数的签名应等价于如下:
1 | bool cmp(const Type1 &a, const Type2 &b); |
虽然签名不必有 const &
,函数也不能修改传递给它的对象,而且必须接受(可为 const
的)类型 Type1
与 Type2
的值,无关乎值类别(从而不允许 Type1 &
,亦不允许 Type1
,除非 Type1
的移动等价于复制 (C++11 起))。
类型 Type1
与 Type2
必须使得 ForwardIt 类型的对象能在解引用后隐式转换到这两个类型。
返回值
指向范围 [first, last)
中最大元素的迭代器。若范围中有多个元素等价于最大元素,则返回指向首个这种元素的迭代器。若范围为空则返回 last
。
复杂度
准确比较 max(N-1,0)
次,其中 N = std::distance(first, last)
。
可能的实现
版本一
1 | template<class ForwardIt> |
版本二
1 | template<class ForwardIt, class Compare> |
示例
1 |
|
输出:
1 | max element at: 5 |
min
定义
1 | template< class T > |
功能
返回给定值中的较小者。
- 1-2) 返回
a
与b
的较小者。 - 3-4) 返回
initializer_list ilist
中值的最小者。 - (1,3) 版本用
operator<
比较元素, (2,4) 版本用给定的比较函数comp
。
参数
a
,b
- 要比较的值ilist
- 拥有要比较的值的initializer_list
cmp
- 比较函数对象(即满足比较 (Compare) 要求的对象),若a
小于b
,则返回 true
。
比较函数的签名应等价于如下:
1 | bool cmp(const Type1 &a, const Type2 &b); |
虽然签名不必有 const &
,函数也不能修改传递给它的对象,而且必须接受(可为 const
的)类型 Type1
与 Type2
的值,无关乎值类别(从而不允许 Type1 &
,亦不允许 Type1
,除非 Type1
的移动等价于复制 (C++11 起))。
类型 Type1
与 Type2
必须使得 T
类型的对象能隐式转换到这两个类型。
返回值
- 1-2)
a
与b
的较小者。若值等价,则返回a
。 - 3-4)
ilist
中的最小值。若有数个等价于最小者的值,则返回最左侧的这种值。
复杂度
- 1-2) 准确一次比较
- 3-4) 准确
ilist.size() - 1
次比较
可能的实现
版本一
1 | template<class T> |
版本二
1 | template<class T, class Compare> |
版本三
1 | template<class T> |
版本四
1 | template<class T, class Compare> |
警告
若参数之一是右值,且返回该参数,则以引用捕获 std::min
的结果会产生一个悬垂引用:
1 | int n = 1; |
示例
1 |
|
输出
1 | smaller of 1 and 9999: 1 |
min_element
定义
1 | template< class ForwardIt > |
功能
寻找范围 [first, last)
中的最小元素。
1) 用 operator<
比较元素。
2) 用给定的二元比较函数 comp
比较元素。
参数
first
,last
- 定义要检验范围的向前迭代器comp
- 比较函数对象(即满足比较 (Compare) 要求的对象),若a
小于b
,则返回true
。
比较函数的签名应等价于如下:
1 | bool cmp(const Type1 &a, const Type2 &b); |
虽然签名不必有 const &
,函数也不能修改传递给它的对象,而且必须接受(可为 const
的)类型 Type1
与 Type2
的值,无关乎值类别(从而不允许 Type1 &
,亦不允许 Type1
,除非 Type1
的移动等价于复制 (C++11 起))。
类型 Type1
与 Type2
必须使得 ForwardIt
类型的对象能在解引用后隐式转换到这两个类型。
返回值
指向范围 [first, last)
中最小元素的迭代器。若范围中有多个元素等价于最小元素,则返回指向首个这种元素的迭代器。若范围为空则返回 last
。
复杂度
准确比较 max(N-1,0)
次,其中 N = std::distance(first, last)
。
可能的实现
版本一
1 | template<class ForwardIt> |
版本二
1 | template<class ForwardIt, class Compare> |
示例
1 |
|
输出:
1 | min element at: 1 |
排列操作
定义于头文件 <algorithm>
next_permutation
定义
1 | template< class BidirIt > |
功能
变换范围 [first, last)
为来自所有按相对于 operator<
或 comp
的字典序的下个排列。若这种排列存在则返回 true
,否则变换范围为首个排列(如同用 std::sort(first, last)
)并返回 false
。
参数
first
,last
- 要重排的元素范围comp
- 比较函数对象(即满足比较 (Compare) 要求的对象),若首个参数小于第二个,则返回true
。
比较函数的签名应等价于如下:
1 | bool cmp(const Type1 &a, const Type2 &b); |
虽然签名不必有 const &
,函数也不能修改传递给它的对象,而且必须接受(可为 const
的)类型 Type1
与 Type2
的值,无关乎值类别(从而不允许 Type1 &
,亦不允许Type1
,除非 Type1
的移动等价于复制 (C++11 起))。
类型 Type1
与 Type2
必须使得 BidirIt
类型的对象能在解引用后隐式转换到这两个类型。
返回值
若新排列按字典序大于旧者则为 true
。若抵达最后重排并重置范围为首个排列则为 false
。
复杂度
至多 N/2
次交换,其中 N = std::distance(first, last)
。
典型实现在排列的整个序列上,平均每次调用使用约 3 次比较和 1.5 次交换。
可能的实现
1 | template<class BidirIt> |
示例
下列代码打印字符串 “aba
“ 的全部三种排列
1 |
|
输出
1 | aab |
prev_permutation
定义
1 | template< class BidirIt > |
功能
变换范围 [first, last)
为来自于相对于 operator<
或 comp
的字典序的所有排列集合的上个排列。若这种排列存在则返回 true
,否则变换范围为末排列(如同用 std::sort(first, last); std::reverse(first, last);
)并返回 false
。
返回值
若新排列按字典序前趋旧排列则为 true
。若抵达首个排列并重置范围为最末排列则为 false
。
复杂度
至多 (last-first)/2
次交换。
典型实现在排列的整个序列上,平均每次调用使用约 3 次比较和 1.5 次交换。
可能的实现
1 | template<class BidirIt> |
示例
下列代码以逆序打印字符串 “abc
“ 的所有六个排列
1 |
|
输出
1 | cba cab bca bac acb abc |