跳到主要内容

算法

C++ 算法库是函数集合,旨在更轻松地编写正确高效富有表现力可重用的代码。

它提供了一组通用、高度优化的算法,可用于执行各种任务,例如在列表中搜索项目、对数据集合进行排序或操作容器的内容。

使用算法库的主要好处之一是它允许您编写更易于理解且不易出错的代码。所有算法都具有几乎普遍认可的名称,这有助于理解使用它们的某些代码部分的作用,而无需进行大量深入研究。由于标准库中的算法经过了彻底的测试优化,您可以依靠它们正确高效地工作。这可以节省您开发软件的时间和精力,并有助于降低在代码中引入错误的风险。

算法库的另一个好处是它促进了代码重用。通过使用库提供的算法,您可以避免重新实现常见的操作,这可以节省时间并使代码更易于维护。

总的来说,C++ 算法库是 C++ 程序员的重要工具,它使编写可靠高效可重用的代码变得更容易。

用法

要使用这些算法,您必须包含 <algorithm> 头文件,如下所示:

#include <algorithm>

然后您可以在代码中使用它们

main.cpp
#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector<int> numbers = { 5, 12, 2137, 1, -5, 22, 96 };
std::ranges::sort(numbers);

for(int number : numbers) {
std::cout << number << ' ';
}
}
结果(控制台)
-5 1 5 12 22 96 2137
区间版本 vs 普通版本

如您在上面的示例中看到的,算法有两种版本:区间版本普通版本。区间版本随 C++20 标准引入 C++。如果您有足够新的编译器,您应该能够使用它。

两者之间的基本区别在于,普通版本只接受迭代器,而区间版本更方便,允许传递整个区间并启用使用投影

区间版本也不易出错,因为您不会不小心传递无效的迭代器(它也比普通版本更好地处理一些高级问题)。

综上所述,使用区间版本更加有益和方便,因此如果可以,请优先选择区间版本。

区间和迭代器

迭代器

迭代是重复一个过程的动作,在容器的情况下,迭代意味着以特定顺序遍历容器,同时获取其每个元素。

迭代器是具有指针语义的特殊对象(具有某些语义基本意味着行为像某些东西,指针语义意味着迭代器对象在大多数方面都像指针一样,它们可以被解引用,递增等。指针也是有效的迭代器),它们用于迭代容器(如字符串、数组、映射、集合等)。

它们通过 begin()end() 函数及其变体获得

  • cbegin()/cend() - 返回容器的常量迭代器(您无法通过它更改内容)
  • rbegin()/rend() - 返回容器的反向迭代器(按相反顺序迭代)
  • crbegin()/crend() - 返回容器的常量反向迭代器(按相反顺序迭代,并且您无法通过它更改内容)

并非所有容器都具有所有变体,例如 std::unordered_set 没有 rcr 版本。

不同的迭代器有不同的类型,它们的工作方式略有不同,但是您可以使用迭代器做的最基本的事情是

  • 递增它(it++++it),它遍历容器中的下一个对象
  • 解引用它(*it),它返回迭代器指向的值

以下是使用迭代器与 std::vector 的几个示例

main.cpp
#include <iostream>
#include <vector>

int main() {
std::vector<int> numbers = { 5, 12, 2137, 1, -5, 22, 96 };

// We obtain the iterator here,
// we use the `c` version because we don't intend to change the contents of the vector,
// we only want to print it
std::vector<int>::const_iterator begin = numbers.cbegin();
std::vector<int>::const_iterator end = numbers.cend();

// here we first check if begin is not equal to end, if it is, then we've traversed the entire container
// if it's not, we print the number
// then we increment the iterator
for(; begin != end; ++begin) {
// *begin means "access the element the iterator points to"
std::cout << *begin << ' ';
}
}
结果(控制台)
5 12 2137 1 -5 22 96

现在,请注意我们每次都必须手动指定类型(std::vector<int>::iteratorstd::vector<int>::reverse_iterator 等)。这不是很方便。为此,您可以使用 auto 占位符

auto begin = numbers.begin();
auto begin = numbers.rbegin();
auto begin = numbers.crbegin();

auto 为我们推断类型,并且没有性能损失。代码以这种方式更易于阅读,因此如果可以,请优先使用它。在此处阅读更多相关信息:auto

范围

那么范围到底是什么?C++ 中的确切定义和内部工作原理有点复杂,但范围可以定义为我们可以迭代的任何事物。一个数组、向量、字符串、映射等。

所有范围化算法都接受一个范围。正如迭代器可以有不同的类型和略微不同的行为一样,某些范围也与其他范围不同,不能与某些算法一起使用。

算法列表

搜索

公开ranges::find (自 C++20 起)查找满足特定条件的第一个元素。
公开find查找满足特定条件的第一个元素。
公开ranges::find_if (自 C++20 起)查找满足特定谓词的第一个元素。
公开find_if查找满足特定谓词的第一个元素。
公开ranges::find_if_not (自 C++20 起)查找满足特定谓词的第一个元素。
公开find_if_not (自 C++11 起)查找满足特定谓词的第一个元素。
公开ranges::find_first_of (自 C++20 起)在一个范围中搜索另一个范围中的任何元素。
公开find_first_of在一个范围中搜索另一个范围中的任何元素。
公开ranges::find_end (自 C++20 起)在某个范围内查找元素的最后一个序列。
公开find_end在某个范围内查找元素的最后一个序列。
公开ranges::find_last (自 C++20 起)查找等于某个值的最后一个元素。
公开ranges::find_last_if (自 C++20 起)查找满足特定条件的最后一个元素。
公开ranges::find_last_if_not (自 C++20 起)查找满足特定条件的最后一个元素。
公开ranges::adjacent_find (自 C++20 起)查找满足条件的相邻的两个项目。
公开adjacent_find查找满足条件的相邻的两个项目。
公开ranges::search (自 C++20 起)搜索元素范围。
公开搜索搜索元素范围。
公开ranges::search_n (自 C++20 起)在范围中搜索连续的元素序列。
公开search_n在范围中搜索连续的元素序列。

确定条件

公开ranges::all_of (自 C++20 起)检查范围中的所有元素是否满足条件。
公开all_of (自 C++11 起)检查范围中的所有元素是否满足条件。
公开ranges::any_of (自 C++20 起)检查范围中的任何元素是否满足条件。
公开any_of (自 C++11 起)检查范围中的任何元素是否满足条件。
公开ranges::none_of (自 C++20 起)检查范围中是否没有元素满足条件。
公开none_of (自 C++11 起)检查范围中是否没有元素满足条件。
公开ranges::count (自 C++20 起)返回某些元素的数量。
公开count返回某些元素的数量。
公开ranges::count_if (自 C++20 起)返回满足特定条件的元素数量。
公开count_if返回满足特定条件的元素数量。
公开ranges::mismatch (自 C++20 起)查找两个范围首次出现不同的位置。
公开mismatch查找两个范围首次出现不同的位置。
公开ranges::starts_with (自 C++20 起)检查一个范围是否以另一个范围开头。
公开ranges::ends_with (自 C++20 起)检查一个范围是否以另一个范围结尾。

其他非修改操作

公开ranges::for_each (自 C++20 起)将函数应用于元素范围。
公开for_each将函数应用于元素范围。
公开ranges::for_each_n (自 C++20 起)将函数应用于由迭代器和大小组成的元素范围。
公开for_each_n (自 C++17 起)将函数应用于由迭代器和大小组成的元素范围。

随机操作

公开random_shuffle (在 C++17 中已移除)在 C++14 中已弃用,在 C++17 中已移除,请改用std::shuffle
随机重新排列范围内的元素。
公开ranges::shuffle (自 C++20 起)随机重新排列范围内的元素。
公开shuffle (自 C++11 起)随机重新排列范围内的元素。
std::random_shuffle 更推荐的方法。
公开ranges::sample (自 C++20 起)从序列中选择 n 个随机元素。
公开sample (自 C++17 起)从序列中选择 n 个随机元素。

修改

公开swap交换两个对象的值。
公开ranges::copy (自 C++20 起)将元素范围复制到新位置。
公开copy将元素范围复制到新位置。
公开ranges::copy_if (自 C++20 起)将满足条件的元素从一个范围复制到新位置。
公开copy_if (自 C++11 起)将满足条件的元素从一个范围复制到新位置。
公开ranges::copy_n (自 C++20 起)将指定数量的元素从一个范围复制到新位置。
公开copy_n (自 C++11 起)将指定数量的元素从一个范围复制到新位置。
公开ranges::copy_backward (自 C++20 起)反向复制元素范围。
公开copy_backward反向复制元素范围。
公开ranges::move (自 C++20 起)将元素范围移动到新位置。
公开move将元素范围移动到新位置。
公开ranges::move_backward (自 C++20 起)将元素范围反向移动到新位置。
公开move_backward将元素范围反向移动到新位置。
公开ranges::transform (自 C++20 起)将函数应用于元素范围。
公开transform将函数应用于元素范围。
公开ranges::reverse (自 C++20 起)反转元素的顺序。
公开reverse反转元素的顺序。
公开ranges::reverse_copy (自 C++20 起)创建范围的反向副本。
公开reverse_copy创建范围的反向副本。
公开ranges::fill (自 C++20 起)将给定值复制赋值给范围中的每个元素。
公开fill将给定值复制赋值给范围中的每个元素。
公开ranges::fill_n (自 C++20 起)将一个值复制赋值给指定数量的元素。
公开fill_n将一个值复制赋值给指定数量的元素。
公开ranges::generate (自 C++20 起)将连续函数调用的结果赋值给范围中的每个元素。
公开generate将连续函数调用的结果赋值给范围中的每个元素。
公开ranges::remove (自 C++20 起)移除等于 value 的元素。
公开remove移除等于 value 的元素。
公开ranges::remove_if (自 C++20 起)移除满足特定条件的元素。
公开remove_if移除满足特定条件的元素。
公开ranges::remove_copy (自 C++20 起)复制元素范围,省略与 value 相等的元素。
公开remove_copy复制元素范围,省略与 value 相等的元素。
公开ranges::remove_copy_if (自 C++20 起)复制元素范围,省略满足谓词的元素。
公开remove_copy_if复制元素范围,省略满足谓词的元素。
公开ranges::replace (自 C++20 起)将旧值替换为新值。
公开replace将旧值替换为新值。
公开ranges::replace_if (自 C++20 起)将满足谓词的值替换为新值。
公开replace_if将满足谓词的值替换为新值。
公开ranges::replace_copy (自 C++20 起)复制一个范围,将等于旧值的元素替换为新值。
公开replace_copy复制一个范围,将等于旧值的元素替换为新值。
公开ranges::replace_copy_if (自 C++20 起)复制一个范围,将满足谓词的元素替换为新值。
公开replace_copy_if复制一个范围,将满足谓词的元素替换为新值。
公开ranges::swap_ranges (自 C++20 起)交换两个范围。
公开swap_ranges交换两个范围。
公开iter_swap交换给定迭代器指向的元素的值。
公开ranges::rotate (自 C++20 起)旋转范围中的元素。
公开rotate旋转范围中的元素。
公开ranges::rotate_copy (自 C++20 起)复制并旋转元素范围。
公开rotate_copy复制并旋转元素范围。
公开ranges::shift_left (自 C++23 起)将范围内的元素向左移动。
公开shift_left (自 C++20 起)将范围内的元素向左移动。
公开ranges::shift_right (自 C++23 起)将范围内的元素向右移动。
公开shift_right (自 C++20 起)将范围内的元素向右移动。
公开ranges::unique (自 C++20 起)删除范围中元素的连续重复项。
公开unique删除范围中元素的连续重复项。
公开ranges::unique_copy (自 C++20 起)创建没有连续重复项的范围副本。
公开unique_copy创建没有连续重复项的范围副本。

分区

公开ranges::is_partitioned (自 C++20 起)判断范围是否被给定谓词分区。
公开is_partitioned (自 C++11 起)判断范围是否被给定谓词分区。
公开ranges::partition (自 C++20 起)根据谓词将元素范围分为两组。
公开partition (自 C++11 起)根据谓词将元素范围分为两组。
公开ranges::partition_copy (自 C++20 起)复制范围并将元素分为两组。
公开partition_copy (自 C++11 起)复制范围并将元素分为两组。
公开ranges::stable_partition (自 C++20 起)将元素分为两组,同时保持其相对顺序。
公开stable_partition将元素分为两组,同时保持其相对顺序。
公开ranges::partition_point (自 C++20 起)定位范围的分区点。
公开partition_point (自 C++11 起)定位范围的分区点。

排序

公开ranges::sort (自 C++20 起)将范围(默认为)升序排序。
公开sort将范围(默认为)升序排序。
公开ranges::stable_sort (自 C++20 起)将范围(默认为)升序排序,同时保持相等元素之间的顺序。
公开stable_sort将范围(默认为)升序排序,同时保持相等元素之间的顺序。
公开ranges::partial_sort (自 C++20 起)排序范围的第一个 N 个元素。
公开partial_sort排序范围的第一个 N 个元素。
公开ranges::partial_sort_copy (自 C++20 起)复制并部分排序元素范围。
公开partial_sort_copy复制并部分排序元素范围。
公开ranges::stable_sort (自 C++20 起)部分排序给定范围,确保它由给定元素分区。
公开stable_sort部分排序给定范围,确保它由给定元素分区。
公开ranges::is_sorted (自 C++20 起)检查范围是否已排序。
公开is_sorted检查范围是否已排序。
公开ranges::is_sorted_until (自 C++20 起)查找最大已排序子范围。
公开is_sorted_until查找最大已排序子范围。

二分查找(在已排序范围内)

公开ranges::binary_search (自 C++20 起)在部分有序范围内搜索元素。
公开binary_search在部分有序范围内搜索元素。
公开ranges::lower_bound (自 C++20 起)返回指向第一个不小于给定值的元素的迭代器。
公开lower_bound返回指向第一个不小于给定值的元素的迭代器。
公开ranges::upper_bound (自 C++20 起)返回指向第一个大于给定值的元素的迭代器。
公开upper_bound返回指向第一个大于给定值的元素的迭代器。
公开ranges::equal_range (自 C++20 起)返回与特定键匹配的元素范围。
公开equal_range返回与特定键匹配的元素范围。

集合(在已排序范围内)

公开ranges::includes (自 C++20 起)如果一个序列是另一个序列的子序列,则返回 true
公开includes如果一个序列是另一个序列的子序列,则返回 true
公开ranges::set_difference (自 C++20 起)计算两个集合之间的差集。
公开set_difference计算两个集合之间的差集。
公开ranges::set_intersection (自 C++20 起)计算两个集合之间的交集。
公开set_intersection计算两个集合之间的交集。
公开ranges::set_symmetric_difference (自 C++20 起)计算两个集合之间的对称差集。
公开set_symmetric_difference计算两个集合之间的对称差集。
公开ranges::set_union (自 C++20 起)计算两个集合之间的并集。
公开set_union计算两个集合之间的并集。

已排序范围的其他操作

公开ranges::merge (自 C++20 起)合并两个已排序的范围。
公开merge合并两个已排序的范围。
公开ranges::inplace_merge (自 C++20 起)就地合并两个已排序的范围。
公开inplace_merge就地合并两个已排序的范围。

公开ranges::is_heap (自 C++20 起)检查给定范围是否为最大堆。
公开is_heap检查给定范围是否为最大堆。
公开ranges::is_heap_until (自 C++20 起)检查给定范围是否为最大堆。
公开is_heap_until检查给定范围是否为最大堆。
公开ranges::make_heap (自 C++20 起)从元素范围创建最大堆。
公开make_heap从元素范围创建最大堆。
公开ranges::push_heap (自 C++20 起)向最大堆添加元素。
公开push_heap向最大堆添加元素。
公开ranges::pop_heap (自 C++20 起)向最大堆添加元素。
公开pop_heap向最大堆添加元素。
公开ranges::sort_heap (自 C++20 起)将最大堆转换为升序排列的元素范围。
公开sort_heap将最大堆转换为升序排列的元素范围。

最小值/最大值

公开ranges::min (自 C++20 起)返回给定值中的最小值。
公开min返回给定值中的最小值。
公开ranges::max (自 C++20 起)返回给定值中的最大值。
公开max返回给定值中的最大值。
公开ranges::max_element (自 C++20 起)返回范围中的最大元素。
公开max_element返回范围中的最大元素。
公开ranges::min_element (自 C++20 起)返回范围中的最小元素。
公开min_element返回范围中的最小元素。
公开ranges::minmax (自 C++20 起)返回给定值中的最小值和最大值。
公开minmax返回给定值中的最小值和最大值。
公开ranges::minmax_element (自 C++20 起)返回范围中的最小和最大元素。
公开minmax_element返回范围中的最小和最大元素。
公开ranges::clamp (自 C++20 起)将值限制在一对边界值之间。
公开clamp将值限制在一对边界值之间。

比较

公开ranges::equal (自 C++20 起)确定两组元素是否相同。
公开equal确定两组元素是否相同。
公开ranges::lexicographical_compare (自 C++20 起)如果一个范围在字典序上小于另一个,则返回 true
公开lexicographical_compare如果一个范围在字典序上小于另一个,则返回 true
公开lexicographical_compare_three_way使用三向比较比较两个范围。

排列

公开ranges::is_permutation (自 C++20 起)确定一个序列是否是另一个序列的排列。
公开is_permutation (自 C++11 起)确定一个序列是否是另一个序列的排列。
公开ranges::next_permutation (自 C++20 起)生成元素范围的下一个字典序更大的排列。
公开next_permutation (自 C++11 起)生成元素范围的下一个字典序更大的排列。
公开ranges::prev_permutation (自 C++20 起)生成元素范围的下一个字典序更小的排列。
公开prev_permutation (自 C++11 起)生成元素范围的下一个字典序更小的排列。

数值

公开ranges::iota (自 C++23 起)用起始值的连续增量填充一个范围。
公开iota (自 C++11 起)用起始值的连续增量填充一个范围。
公开accumulate对元素范围求和或折叠/规约
公开inner_product计算两个元素范围的内积。
公开adjacent_difference计算范围中相邻元素之间的差值。
公开partial_sum计算元素范围的部分和。
公开reduce (自 C++17 起)类似于std::accumulate,但顺序不确定。
公开exclusive_scan (自 C++17 起)类似于std::partial_sum,从第 i 个和中排除第 i 个输入元素。
公开inclusive_scan (自 C++17 起)类似于std::partial_sum,从第 i 个和中包含第 i 个输入元素。
公开transform_reduce (自 C++17 起)应用一个可调用对象,然后无序地进行归约。
公开transform_exclusive_scan (自 C++17 起)应用一个可调用对象,然后计算独占扫描。
公开transform_inclusive_scan (自 C++17 起)应用一个可调用对象,然后计算包含扫描。

未初始化内存上的操作

公开uninitialized_copy将一系列对象复制到未初始化的内存区域。
公开uninitialized_copy将一系列对象复制到未初始化的内存区域。
公开uninitialized_copy_n将指定数量的元素从一个范围复制到未初始化的内存区域。
公开uninitialized_copy_n将指定数量的元素从一个范围复制到未初始化的内存区域。
公开uninitialized_fill填充未初始化范围。
公开uninitialized_fill填充未初始化范围。
公开uninitialized_fill_n填充由起始和计数定义的未初始化范围。
公开uninitialized_fill_n填充由起始和计数定义的未初始化范围。
公开uninitialized_fill_n填充由起始和计数定义的未初始化范围。
公开uninitialized_fill_n填充由起始和计数定义的未初始化范围。
公开uninitialized_move (自 C++17 起)将多个对象移动到未初始化的内存区域。
公开uninitialized_move将多个对象移动到未初始化的内存区域。
公开uninitialized_move_n (自 C++17 起)将多个对象移动到未初始化的内存区域。
公开uninitialized_move_n将多个对象移动到未初始化的内存区域。
公开uninitialized_default_construct (自 C++17 起)在由范围定义的未初始化内存区域中,通过默认初始化构造对象。
公开uninitialized_default_construct将多个对象移动到未初始化的内存区域。
公开uninitialized_default_construct_n (自 C++17 起)在由起始和计数定义的未初始化内存区域中,通过默认初始化构造对象。
公开uninitialized_default_construct_n在由起始和计数定义的未初始化内存区域中,通过默认初始化构造对象。
公开uninitialized_value_construct (自 C++17 起)在由范围定义的未初始化内存区域中,通过值初始化构造对象。
公开uninitialized_value_construct在由范围定义的未初始化内存区域中,通过值初始化构造对象。
公开uninitialized_value_construct_n (自 C++17 起)在由起始和大小定义的未初始化内存区域中,通过值初始化构造对象。
公开uninitialized_value_construct_n在由起始和大小定义的未初始化内存区域中,通过值初始化构造对象。
公开销毁 (自 C++17 起)销毁一系列对象。
公开销毁销毁一系列对象。
公开destroy_n (自 C++17 起)销毁多个对象。
公开destroy_n销毁多个对象。
公开destroy_at (自 C++17 起)销毁给定地址处的对象。
公开destroy_at销毁给定地址处的对象。
公开construct_at (自 C++17 起)在给定地址处创建对象。
公开construct_at在给定地址处创建对象。

C 算法

公开qsort对未指定类型的元素范围进行排序。
公开bsearch在数组中搜索未指定类型的元素。

算法

C++ 算法库是函数集合,旨在更轻松地编写正确高效富有表现力可重用的代码。

它提供了一组通用、高度优化的算法,可用于执行各种任务,例如在列表中搜索项目、对数据集合进行排序或操作容器的内容。

使用算法库的主要好处之一是它允许您编写更易于理解且不易出错的代码。所有算法都具有几乎普遍认可的名称,这有助于理解使用它们的某些代码部分的作用,而无需进行大量深入研究。由于标准库中的算法经过了彻底的测试优化,您可以依靠它们正确高效地工作。这可以节省您开发软件的时间和精力,并有助于降低在代码中引入错误的风险。

算法库的另一个好处是它促进了代码重用。通过使用库提供的算法,您可以避免重新实现常见的操作,这可以节省时间并使代码更易于维护。

总的来说,C++ 算法库是 C++ 程序员的重要工具,它使编写可靠高效可重用的代码变得更容易。

用法

要使用这些算法,您必须包含 <algorithm> 头文件,如下所示:

#include <algorithm>

然后您可以在代码中使用它们

main.cpp
#include <algorithm>
#include <iostream>
#include <vector>

int main() {
std::vector<int> numbers = { 5, 12, 2137, 1, -5, 22, 96 };
std::ranges::sort(numbers);

for(int number : numbers) {
std::cout << number << ' ';
}
}
结果(控制台)
-5 1 5 12 22 96 2137
区间版本 vs 普通版本

如您在上面的示例中看到的,算法有两种版本:区间版本普通版本。区间版本随 C++20 标准引入 C++。如果您有足够新的编译器,您应该能够使用它。

两者之间的基本区别在于,普通版本只接受迭代器,而区间版本更方便,允许传递整个区间并启用使用投影

区间版本也不易出错,因为您不会不小心传递无效的迭代器(它也比普通版本更好地处理一些高级问题)。

综上所述,使用区间版本更加有益和方便,因此如果可以,请优先选择区间版本。

区间和迭代器

迭代器

迭代是重复一个过程的动作,在容器的情况下,迭代意味着以特定顺序遍历容器,同时获取其每个元素。

迭代器是具有指针语义的特殊对象(具有某些语义基本意味着行为像某些东西,指针语义意味着迭代器对象在大多数方面都像指针一样,它们可以被解引用,递增等。指针也是有效的迭代器),它们用于迭代容器(如字符串、数组、映射、集合等)。

它们通过 begin()end() 函数及其变体获得

  • cbegin()/cend() - 返回容器的常量迭代器(您无法通过它更改内容)
  • rbegin()/rend() - 返回容器的反向迭代器(按相反顺序迭代)
  • crbegin()/crend() - 返回容器的常量反向迭代器(按相反顺序迭代,并且您无法通过它更改内容)

并非所有容器都具有所有变体,例如 std::unordered_set 没有 rcr 版本。

不同的迭代器有不同的类型,它们的工作方式略有不同,但是您可以使用迭代器做的最基本的事情是

  • 递增它(it++++it),它遍历容器中的下一个对象
  • 解引用它(*it),它返回迭代器指向的值

以下是使用迭代器与 std::vector 的几个示例

main.cpp
#include <iostream>
#include <vector>

int main() {
std::vector<int> numbers = { 5, 12, 2137, 1, -5, 22, 96 };

// We obtain the iterator here,
// we use the `c` version because we don't intend to change the contents of the vector,
// we only want to print it
std::vector<int>::const_iterator begin = numbers.cbegin();
std::vector<int>::const_iterator end = numbers.cend();

// here we first check if begin is not equal to end, if it is, then we've traversed the entire container
// if it's not, we print the number
// then we increment the iterator
for(; begin != end; ++begin) {
// *begin means "access the element the iterator points to"
std::cout << *begin << ' ';
}
}
结果(控制台)
5 12 2137 1 -5 22 96

现在,请注意我们每次都必须手动指定类型(std::vector<int>::iteratorstd::vector<int>::reverse_iterator 等)。这不是很方便。为此,您可以使用 auto 占位符

auto begin = numbers.begin();
auto begin = numbers.rbegin();
auto begin = numbers.crbegin();

auto 为我们推断类型,并且没有性能损失。代码以这种方式更易于阅读,因此如果可以,请优先使用它。在此处阅读更多相关信息:auto

范围

那么范围到底是什么?C++ 中的确切定义和内部工作原理有点复杂,但范围可以定义为我们可以迭代的任何事物。一个数组、向量、字符串、映射等。

所有范围化算法都接受一个范围。正如迭代器可以有不同的类型和略微不同的行为一样,某些范围也与其他范围不同,不能与某些算法一起使用。

算法列表

搜索

公开ranges::find (自 C++20 起)查找满足特定条件的第一个元素。
公开find查找满足特定条件的第一个元素。
公开ranges::find_if (自 C++20 起)查找满足特定谓词的第一个元素。
公开find_if查找满足特定谓词的第一个元素。
公开ranges::find_if_not (自 C++20 起)查找满足特定谓词的第一个元素。
公开find_if_not (自 C++11 起)查找满足特定谓词的第一个元素。
公开ranges::find_first_of (自 C++20 起)在一个范围中搜索另一个范围中的任何元素。
公开find_first_of在一个范围中搜索另一个范围中的任何元素。
公开ranges::find_end (自 C++20 起)在某个范围内查找元素的最后一个序列。
公开find_end在某个范围内查找元素的最后一个序列。
公开ranges::find_last (自 C++20 起)查找等于某个值的最后一个元素。
公开ranges::find_last_if (自 C++20 起)查找满足特定条件的最后一个元素。
公开ranges::find_last_if_not (自 C++20 起)查找满足特定条件的最后一个元素。
公开ranges::adjacent_find (自 C++20 起)查找满足条件的相邻的两个项目。
公开adjacent_find查找满足条件的相邻的两个项目。
公开ranges::search (自 C++20 起)搜索元素范围。
公开搜索搜索元素范围。
公开ranges::search_n (自 C++20 起)在范围中搜索连续的元素序列。
公开search_n在范围中搜索连续的元素序列。

确定条件

公开ranges::all_of (自 C++20 起)检查范围中的所有元素是否满足条件。
公开all_of (自 C++11 起)检查范围中的所有元素是否满足条件。
公开ranges::any_of (自 C++20 起)检查范围中的任何元素是否满足条件。
公开any_of (自 C++11 起)检查范围中的任何元素是否满足条件。
公开ranges::none_of (自 C++20 起)检查范围中是否没有元素满足条件。
公开none_of (自 C++11 起)检查范围中是否没有元素满足条件。
公开ranges::count (自 C++20 起)返回某些元素的数量。
公开count返回某些元素的数量。
公开ranges::count_if (自 C++20 起)返回满足特定条件的元素数量。
公开count_if返回满足特定条件的元素数量。
公开ranges::mismatch (自 C++20 起)查找两个范围首次出现不同的位置。
公开mismatch查找两个范围首次出现不同的位置。
公开ranges::starts_with (自 C++20 起)检查一个范围是否以另一个范围开头。
公开ranges::ends_with (自 C++20 起)检查一个范围是否以另一个范围结尾。

其他非修改操作

公开ranges::for_each (自 C++20 起)将函数应用于元素范围。
公开for_each将函数应用于元素范围。
公开ranges::for_each_n (自 C++20 起)将函数应用于由迭代器和大小组成的元素范围。
公开for_each_n (自 C++17 起)将函数应用于由迭代器和大小组成的元素范围。

随机操作

公开random_shuffle (在 C++17 中已移除)在 C++14 中已弃用,在 C++17 中已移除,请改用std::shuffle
随机重新排列范围内的元素。
公开ranges::shuffle (自 C++20 起)随机重新排列范围内的元素。
公开shuffle (自 C++11 起)随机重新排列范围内的元素。
std::random_shuffle 更推荐的方法。
公开ranges::sample (自 C++20 起)从序列中选择 n 个随机元素。
公开sample (自 C++17 起)从序列中选择 n 个随机元素。

修改

公开swap交换两个对象的值。
公开ranges::copy (自 C++20 起)将元素范围复制到新位置。
公开copy将元素范围复制到新位置。
公开ranges::copy_if (自 C++20 起)将满足条件的元素从一个范围复制到新位置。
公开copy_if (自 C++11 起)将满足条件的元素从一个范围复制到新位置。
公开ranges::copy_n (自 C++20 起)将指定数量的元素从一个范围复制到新位置。
公开copy_n (自 C++11 起)将指定数量的元素从一个范围复制到新位置。
公开ranges::copy_backward (自 C++20 起)反向复制元素范围。
公开copy_backward反向复制元素范围。
公开ranges::move (自 C++20 起)将元素范围移动到新位置。
公开move将元素范围移动到新位置。
公开ranges::move_backward (自 C++20 起)将元素范围反向移动到新位置。
公开move_backward将元素范围反向移动到新位置。
公开ranges::transform (自 C++20 起)将函数应用于元素范围。
公开transform将函数应用于元素范围。
公开ranges::reverse (自 C++20 起)反转元素的顺序。
公开reverse反转元素的顺序。
公开ranges::reverse_copy (自 C++20 起)创建范围的反向副本。
公开reverse_copy创建范围的反向副本。
公开ranges::fill (自 C++20 起)将给定值复制赋值给范围中的每个元素。
公开fill将给定值复制赋值给范围中的每个元素。
公开ranges::fill_n (自 C++20 起)将一个值复制赋值给指定数量的元素。
公开fill_n将一个值复制赋值给指定数量的元素。
公开ranges::generate (自 C++20 起)将连续函数调用的结果赋值给范围中的每个元素。
公开generate将连续函数调用的结果赋值给范围中的每个元素。
公开ranges::remove (自 C++20 起)移除等于 value 的元素。
公开remove移除等于 value 的元素。
公开ranges::remove_if (自 C++20 起)移除满足特定条件的元素。
公开remove_if移除满足特定条件的元素。
公开ranges::remove_copy (自 C++20 起)复制元素范围,省略与 value 相等的元素。
公开remove_copy复制元素范围,省略与 value 相等的元素。
公开ranges::remove_copy_if (自 C++20 起)复制元素范围,省略满足谓词的元素。
公开remove_copy_if复制元素范围,省略满足谓词的元素。
公开ranges::replace (自 C++20 起)将旧值替换为新值。
公开replace将旧值替换为新值。
公开ranges::replace_if (自 C++20 起)将满足谓词的值替换为新值。
公开replace_if将满足谓词的值替换为新值。
公开ranges::replace_copy (自 C++20 起)复制一个范围,将等于旧值的元素替换为新值。
公开replace_copy复制一个范围,将等于旧值的元素替换为新值。
公开ranges::replace_copy_if (自 C++20 起)复制一个范围,将满足谓词的元素替换为新值。
公开replace_copy_if复制一个范围,将满足谓词的元素替换为新值。
公开ranges::swap_ranges (自 C++20 起)交换两个范围。
公开swap_ranges交换两个范围。
公开iter_swap交换给定迭代器指向的元素的值。
公开ranges::rotate (自 C++20 起)旋转范围中的元素。
公开rotate旋转范围中的元素。
公开ranges::rotate_copy (自 C++20 起)复制并旋转元素范围。
公开rotate_copy复制并旋转元素范围。
公开ranges::shift_left (自 C++23 起)将范围内的元素向左移动。
公开shift_left (自 C++20 起)将范围内的元素向左移动。
公开ranges::shift_right (自 C++23 起)将范围内的元素向右移动。
公开shift_right (自 C++20 起)将范围内的元素向右移动。
公开ranges::unique (自 C++20 起)删除范围中元素的连续重复项。
公开unique删除范围中元素的连续重复项。
公开ranges::unique_copy (自 C++20 起)创建没有连续重复项的范围副本。
公开unique_copy创建没有连续重复项的范围副本。

分区

公开ranges::is_partitioned (自 C++20 起)判断范围是否被给定谓词分区。
公开is_partitioned (自 C++11 起)判断范围是否被给定谓词分区。
公开ranges::partition (自 C++20 起)根据谓词将元素范围分为两组。
公开partition (自 C++11 起)根据谓词将元素范围分为两组。
公开ranges::partition_copy (自 C++20 起)复制范围并将元素分为两组。
公开partition_copy (自 C++11 起)复制范围并将元素分为两组。
公开ranges::stable_partition (自 C++20 起)将元素分为两组,同时保持其相对顺序。
公开stable_partition将元素分为两组,同时保持其相对顺序。
公开ranges::partition_point (自 C++20 起)定位范围的分区点。
公开partition_point (自 C++11 起)定位范围的分区点。

排序

公开ranges::sort (自 C++20 起)将范围(默认为)升序排序。
公开sort将范围(默认为)升序排序。
公开ranges::stable_sort (自 C++20 起)将范围(默认为)升序排序,同时保持相等元素之间的顺序。
公开stable_sort将范围(默认为)升序排序,同时保持相等元素之间的顺序。
公开ranges::partial_sort (自 C++20 起)排序范围的第一个 N 个元素。
公开partial_sort排序范围的第一个 N 个元素。
公开ranges::partial_sort_copy (自 C++20 起)复制并部分排序元素范围。
公开partial_sort_copy复制并部分排序元素范围。
公开ranges::stable_sort (自 C++20 起)部分排序给定范围,确保它由给定元素分区。
公开stable_sort部分排序给定范围,确保它由给定元素分区。
公开ranges::is_sorted (自 C++20 起)检查范围是否已排序。
公开is_sorted检查范围是否已排序。
公开ranges::is_sorted_until (自 C++20 起)查找最大已排序子范围。
公开is_sorted_until查找最大已排序子范围。

二分查找(在已排序范围内)

公开ranges::binary_search (自 C++20 起)在部分有序范围内搜索元素。
公开binary_search在部分有序范围内搜索元素。
公开ranges::lower_bound (自 C++20 起)返回指向第一个不小于给定值的元素的迭代器。
公开lower_bound返回指向第一个不小于给定值的元素的迭代器。
公开ranges::upper_bound (自 C++20 起)返回指向第一个大于给定值的元素的迭代器。
公开upper_bound返回指向第一个大于给定值的元素的迭代器。
公开ranges::equal_range (自 C++20 起)返回与特定键匹配的元素范围。
公开equal_range返回与特定键匹配的元素范围。

集合(在已排序范围内)

公开ranges::includes (自 C++20 起)如果一个序列是另一个序列的子序列,则返回 true
公开includes如果一个序列是另一个序列的子序列,则返回 true
公开ranges::set_difference (自 C++20 起)计算两个集合之间的差集。
公开set_difference计算两个集合之间的差集。
公开ranges::set_intersection (自 C++20 起)计算两个集合之间的交集。
公开set_intersection计算两个集合之间的交集。
公开ranges::set_symmetric_difference (自 C++20 起)计算两个集合之间的对称差集。
公开set_symmetric_difference计算两个集合之间的对称差集。
公开ranges::set_union (自 C++20 起)计算两个集合之间的并集。
公开set_union计算两个集合之间的并集。

已排序范围的其他操作

公开ranges::merge (自 C++20 起)合并两个已排序的范围。
公开merge合并两个已排序的范围。
公开ranges::inplace_merge (自 C++20 起)就地合并两个已排序的范围。
公开inplace_merge就地合并两个已排序的范围。

公开ranges::is_heap (自 C++20 起)检查给定范围是否为最大堆。
公开is_heap检查给定范围是否为最大堆。
公开ranges::is_heap_until (自 C++20 起)检查给定范围是否为最大堆。
公开is_heap_until检查给定范围是否为最大堆。
公开ranges::make_heap (自 C++20 起)从元素范围创建最大堆。
公开make_heap从元素范围创建最大堆。
公开ranges::push_heap (自 C++20 起)向最大堆添加元素。
公开push_heap向最大堆添加元素。
公开ranges::pop_heap (自 C++20 起)向最大堆添加元素。
公开pop_heap向最大堆添加元素。
公开ranges::sort_heap (自 C++20 起)将最大堆转换为升序排列的元素范围。
公开sort_heap将最大堆转换为升序排列的元素范围。

最小值/最大值

公开ranges::min (自 C++20 起)返回给定值中的最小值。
公开min返回给定值中的最小值。
公开ranges::max (自 C++20 起)返回给定值中的最大值。
公开max返回给定值中的最大值。
公开ranges::max_element (自 C++20 起)返回范围中的最大元素。
公开max_element返回范围中的最大元素。
公开ranges::min_element (自 C++20 起)返回范围中的最小元素。
公开min_element返回范围中的最小元素。
公开ranges::minmax (自 C++20 起)返回给定值中的最小值和最大值。
公开minmax返回给定值中的最小值和最大值。
公开ranges::minmax_element (自 C++20 起)返回范围中的最小和最大元素。
公开minmax_element返回范围中的最小和最大元素。
公开ranges::clamp (自 C++20 起)将值限制在一对边界值之间。
公开clamp将值限制在一对边界值之间。

比较

公开ranges::equal (自 C++20 起)确定两组元素是否相同。
公开equal确定两组元素是否相同。
公开ranges::lexicographical_compare (自 C++20 起)如果一个范围在字典序上小于另一个,则返回 true
公开lexicographical_compare如果一个范围在字典序上小于另一个,则返回 true
公开lexicographical_compare_three_way使用三向比较比较两个范围。

排列

公开ranges::is_permutation (自 C++20 起)确定一个序列是否是另一个序列的排列。
公开is_permutation (自 C++11 起)确定一个序列是否是另一个序列的排列。
公开ranges::next_permutation (自 C++20 起)生成元素范围的下一个字典序更大的排列。
公开next_permutation (自 C++11 起)生成元素范围的下一个字典序更大的排列。
公开ranges::prev_permutation (自 C++20 起)生成元素范围的下一个字典序更小的排列。
公开prev_permutation (自 C++11 起)生成元素范围的下一个字典序更小的排列。

数值

公开ranges::iota (自 C++23 起)用起始值的连续增量填充一个范围。
公开iota (自 C++11 起)用起始值的连续增量填充一个范围。
公开accumulate对元素范围求和或折叠/规约
公开inner_product计算两个元素范围的内积。
公开adjacent_difference计算范围中相邻元素之间的差值。
公开partial_sum计算元素范围的部分和。
公开reduce (自 C++17 起)类似于std::accumulate,但顺序不确定。
公开exclusive_scan (自 C++17 起)类似于std::partial_sum,从第 i 个和中排除第 i 个输入元素。
公开inclusive_scan (自 C++17 起)类似于std::partial_sum,从第 i 个和中包含第 i 个输入元素。
公开transform_reduce (自 C++17 起)应用一个可调用对象,然后无序地进行归约。
公开transform_exclusive_scan (自 C++17 起)应用一个可调用对象,然后计算独占扫描。
公开transform_inclusive_scan (自 C++17 起)应用一个可调用对象,然后计算包含扫描。

未初始化内存上的操作

公开uninitialized_copy将一系列对象复制到未初始化的内存区域。
公开uninitialized_copy将一系列对象复制到未初始化的内存区域。
公开uninitialized_copy_n将指定数量的元素从一个范围复制到未初始化的内存区域。
公开uninitialized_copy_n将指定数量的元素从一个范围复制到未初始化的内存区域。
公开uninitialized_fill填充未初始化范围。
公开uninitialized_fill填充未初始化范围。
公开uninitialized_fill_n填充由起始和计数定义的未初始化范围。
公开uninitialized_fill_n填充由起始和计数定义的未初始化范围。
公开uninitialized_fill_n填充由起始和计数定义的未初始化范围。
公开uninitialized_fill_n填充由起始和计数定义的未初始化范围。
公开uninitialized_move (自 C++17 起)将多个对象移动到未初始化的内存区域。
公开uninitialized_move将多个对象移动到未初始化的内存区域。
公开uninitialized_move_n (自 C++17 起)将多个对象移动到未初始化的内存区域。
公开uninitialized_move_n将多个对象移动到未初始化的内存区域。
公开uninitialized_default_construct (自 C++17 起)在由范围定义的未初始化内存区域中,通过默认初始化构造对象。
公开uninitialized_default_construct将多个对象移动到未初始化的内存区域。
公开uninitialized_default_construct_n (自 C++17 起)在由起始和计数定义的未初始化内存区域中,通过默认初始化构造对象。
公开uninitialized_default_construct_n在由起始和计数定义的未初始化内存区域中,通过默认初始化构造对象。
公开uninitialized_value_construct (自 C++17 起)在由范围定义的未初始化内存区域中,通过值初始化构造对象。
公开uninitialized_value_construct在由范围定义的未初始化内存区域中,通过值初始化构造对象。
公开uninitialized_value_construct_n (自 C++17 起)在由起始和大小定义的未初始化内存区域中,通过值初始化构造对象。
公开uninitialized_value_construct_n在由起始和大小定义的未初始化内存区域中,通过值初始化构造对象。
公开销毁 (自 C++17 起)销毁一系列对象。
公开销毁销毁一系列对象。
公开destroy_n (自 C++17 起)销毁多个对象。
公开destroy_n销毁多个对象。
公开destroy_at (自 C++17 起)销毁给定地址处的对象。
公开destroy_at销毁给定地址处的对象。
公开construct_at (自 C++17 起)在给定地址处创建对象。
公开construct_at在给定地址处创建对象。

C 算法

公开qsort对未指定类型的元素范围进行排序。
公开bsearch在数组中搜索未指定类型的元素。