跳到主要内容

std::exclusive_scan() 算法

// (1)
template< class InputIt, class OutputIt >
constexpr OutputIt exclusive_scan( InputIt first, InputIt last, OutputIt d_first );

// (2)
template< class InputIt, class OutputIt, class BinaryOperation >
constexpr OutputIt exclusive_scan( InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op );

// (3)
template< class InputIt, class OutputIt, class BinaryOperation, class T >
constexpr OutputIt exclusive_scan( InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op, T init );

// (4)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardtIt2 exclusive_scan( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first );

// (5)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryOperation >
ForwardIt2 exclusive_scan( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op );

// (6)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryOperation, class T >
ForwardIt2 exclusive_scan( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op, T init );

使用 binary_op(对于重载 (1, 4),使用 std::plus<>())计算一个专属前缀和操作,范围为 [first; last),使用 init 作为初始值(如果提供),并将结果写入从 d_first 开始的范围。

"专属" 意味着第 i 个输入元素包含在第 i 个和中。

求和操作可以按任意顺序执行,如果 binary_op 不具有结合性,则行为不确定。

形式上,通过 [d_first; d_first + (last - first)) 中的每个迭代器 i 分配值

  • (1, 2, 4, 5) 对于 [first; first + (i - d_first + 1) ) 中每个 j*j... 的广义非交换和,通过 binary_op 计算
  • (3, 6) 对于 [first; first + (i - d_first + 1)) 中每个 jinit, *j... 的广义非交换和,通过 binary_op 计算

其中广义非交换和 GNSUM(op, a1, ..., aN) 定义如下:

  • 如果 N = 1,则为 a1

  • 如果 N > 1,则对于任何 K1 < K + 1 = M ≤ N,为 op(GNSUM(op, a1, ..., aK), GNSUM(op, aM, ..., aN))

  • (4 - 6)(1 - 3) 相同,但根据策略执行。

    重载决议

    这些重载仅在 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>true 时才参与重载决议。  (直到 C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>true 时才参与重载决议。  (自 C++20 起)

未定义行为

binary_op 不应使迭代器(包括结束迭代器)或子范围失效,也不应修改范围 [first, last) 或 [d_first, d_first + (last - first)) 中的元素。

否则,行为未定义

.

参数

first
last

要求和的元素范围。

d_first

目标范围的开始;可以等于 first

init

广义和的初始值。

策略

要使用的执行策略。有关详细信息,请参阅执行策略

binary_op

二元函数对象,将以未指定顺序应用于解引用输入迭代器的结果、其他 binary_op 的结果和 init

类型要求

InputItLegacyInputIterator
OutputItLegacyOutputIterator
ForwardIt1
ForwardIt2
LegacyForwardIterator
  • T(如果提供了 init)必须满足MoveConstructible的要求。以下表达式必须可转换为 T
    • binary_op(init, *first)
    • binary_op(init, init)
    • binary_op(*first, *first)

返回值

指向已写入的最后一个元素之后的元素的迭代器。

复杂度

O(last - first)binary_op 应用。

异常

带有模板参数 ExecutionPolicy 的重载报告错误如下

  • 如果作为算法一部分调用的函数执行抛出异常,并且 ExecutionPolicy标准策略之一,则调用std::terminate。对于任何其他 ExecutionPolicy,行为是实现定义的.
  • 如果算法未能分配内存,则抛出 std::bad_alloc

示例

Main.cpp
#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>

int main()
{
std::vector data {3, 1, 4, 1, 5, 9, 2, 6};

std::cout << "Exclusive sum: ";
std::exclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
0);
std::cout << "\nInclusive sum: ";
std::inclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "));

std::cout << "\n\nExclusive product: ";
std::exclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
1, std::multiplies<>{});
std::cout << "\nInclusive product: ";
std::inclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
std::multiplies<>{});
}
可能输出
Exclusive sum: 0 3 4 8 9 14 23 25
Inclusive sum: 3 4 8 9 14 23 25 31

Exclusive product: 1 3 3 12 12 60 540 1080
Inclusive product: 3 3 12 12 60 540 1080 6480
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”可查看此文档的所有更改。
悬停查看原始许可证。

std::exclusive_scan() 算法

// (1)
template< class InputIt, class OutputIt >
constexpr OutputIt exclusive_scan( InputIt first, InputIt last, OutputIt d_first );

// (2)
template< class InputIt, class OutputIt, class BinaryOperation >
constexpr OutputIt exclusive_scan( InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op );

// (3)
template< class InputIt, class OutputIt, class BinaryOperation, class T >
constexpr OutputIt exclusive_scan( InputIt first, InputIt last, OutputIt d_first, BinaryOperation binary_op, T init );

// (4)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardtIt2 exclusive_scan( ExecutionPolicy&& policy, ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first );

// (5)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryOperation >
ForwardIt2 exclusive_scan( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op );

// (6)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2, class BinaryOperation, class T >
ForwardIt2 exclusive_scan( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first,
BinaryOperation binary_op, T init );

使用 binary_op(对于重载 (1, 4),使用 std::plus<>())计算一个专属前缀和操作,范围为 [first; last),使用 init 作为初始值(如果提供),并将结果写入从 d_first 开始的范围。

"专属" 意味着第 i 个输入元素包含在第 i 个和中。

求和操作可以按任意顺序执行,如果 binary_op 不具有结合性,则行为不确定。

形式上,通过 [d_first; d_first + (last - first)) 中的每个迭代器 i 分配值

  • (1, 2, 4, 5) 对于 [first; first + (i - d_first + 1) ) 中每个 j*j... 的广义非交换和,通过 binary_op 计算
  • (3, 6) 对于 [first; first + (i - d_first + 1)) 中每个 jinit, *j... 的广义非交换和,通过 binary_op 计算

其中广义非交换和 GNSUM(op, a1, ..., aN) 定义如下:

  • 如果 N = 1,则为 a1

  • 如果 N > 1,则对于任何 K1 < K + 1 = M ≤ N,为 op(GNSUM(op, a1, ..., aK), GNSUM(op, aM, ..., aN))

  • (4 - 6)(1 - 3) 相同,但根据策略执行。

    重载决议

    这些重载仅在 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>true 时才参与重载决议。  (直到 C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>true 时才参与重载决议。  (自 C++20 起)

未定义行为

binary_op 不应使迭代器(包括结束迭代器)或子范围失效,也不应修改范围 [first, last) 或 [d_first, d_first + (last - first)) 中的元素。

否则,行为未定义

.

参数

first
last

要求和的元素范围。

d_first

目标范围的开始;可以等于 first

init

广义和的初始值。

策略

要使用的执行策略。有关详细信息,请参阅执行策略

binary_op

二元函数对象,将以未指定顺序应用于解引用输入迭代器的结果、其他 binary_op 的结果和 init

类型要求

InputItLegacyInputIterator
OutputItLegacyOutputIterator
ForwardIt1
ForwardIt2
LegacyForwardIterator
  • T(如果提供了 init)必须满足MoveConstructible的要求。以下表达式必须可转换为 T
    • binary_op(init, *first)
    • binary_op(init, init)
    • binary_op(*first, *first)

返回值

指向已写入的最后一个元素之后的元素的迭代器。

复杂度

O(last - first)binary_op 应用。

异常

带有模板参数 ExecutionPolicy 的重载报告错误如下

  • 如果作为算法一部分调用的函数执行抛出异常,并且 ExecutionPolicy标准策略之一,则调用std::terminate。对于任何其他 ExecutionPolicy,行为是实现定义的.
  • 如果算法未能分配内存,则抛出 std::bad_alloc

示例

Main.cpp
#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
#include <vector>

int main()
{
std::vector data {3, 1, 4, 1, 5, 9, 2, 6};

std::cout << "Exclusive sum: ";
std::exclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
0);
std::cout << "\nInclusive sum: ";
std::inclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "));

std::cout << "\n\nExclusive product: ";
std::exclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
1, std::multiplies<>{});
std::cout << "\nInclusive product: ";
std::inclusive_scan(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "),
std::multiplies<>{});
}
可能输出
Exclusive sum: 0 3 4 8 9 14 23 25
Inclusive sum: 3 4 8 9 14 23 25 31

Exclusive product: 1 3 3 12 12 60 540 1080
Inclusive product: 3 3 12 12 60 540 1080 6480
本文源自此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”可查看此文档的所有更改。
悬停查看原始许可证。