Spec-Zone.ru › C++

std::inclusive_scan

Определено в заголовке <numeric>
(1)
template< class InputIt, class OutputIt >
OutputIt inclusive_scan( InputIt first, 
                         InputIt last, OutputIt d_first );
(с C++17)
(до C++20)
template< class InputIt, class OutputIt >
constexpr OutputIt inclusive_scan( InputIt first, 
                                   InputIt last, OutputIt d_first );
(с C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardtIt2 inclusive_scan( ExecutionPolicy&& policy, ForwardIt1 first, 
                            ForwardIt1 last, ForwardIt2 d_first );
(2) (с C++17)
(3)
template< class InputIt, class OutputIt, class BinaryOperation >
OutputIt inclusive_scan( InputIt first, InputIt last,
                         OutputIt d_first, BinaryOperation binary_op );
(с C++17)
(до C++20)
template< class InputIt, class OutputIt, class BinaryOperation >
constexpr OutputIt inclusive_scan( InputIt first, InputIt last,
                                   OutputIt d_first, BinaryOperation binary_op );
(с C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
          class BinaryOperation >
ForwardIt2 inclusive_scan( ExecutionPolicy&& policy, 
                           ForwardIt1 first, ForwardIt1 last,
                           ForwardIt2 d_first, BinaryOperation binary_op );
(4) (с C++17)
(5)
template< class InputIt, class OutputIt, class BinaryOperation, class T >
OutputIt inclusive_scan( InputIt first, InputIt last, OutputIt d_first,
                         BinaryOperation binary_op, T init );
(с C++17)
(до C++20)
template< class InputIt, class OutputIt, class BinaryOperation, class T >
constexpr OutputIt inclusive_scan( InputIt first, InputIt last, OutputIt d_first,
                                   BinaryOperation binary_op, T init );
(с C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2,
          class BinaryOperation, class T >
ForwardIt2 inclusive_scan( ExecutionPolicy&& policy, 
                           ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first, 
                           BinaryOperation binary_op, T init );
(6) (с C++17)

Вычисляет операцию накопительной суммы с включением, используя binary_op (или std::plus<>() для перегрузок (1,2)) для диапазона [first, last), используя init в качестве начального значения (если указано), и записывает результаты в диапазон, начинающийся с d_first. «Включительно» означает, что i-й элемент входных данных включён в i-ю сумму.

Формально, присваивает каждому итератору i в [d_first, d_first + (last - first)) значение:

  • для перегрузок (1-4), обобщенную некоммутативную сумму *j... для каждого j в [first, first + (i - d_first + 1)) над binary_op
  • для перегрузок (5,6), обобщенную некоммутативную сумму init, *j... для каждого j в [first, first + (i - d_first + 1)) над binary_op

где обобщенная некоммутативная сумма GNSUM(op, a1, ..., aN) определяется следующим образом:

  • если N = 1, a1
  • если N > 1, op(GNSUM(op, a1, ..., aK), GNSUM(op, aM, ..., aN)) для любого K, где 1 < K + 1 = M ≤ N

Другими словами, операции суммирования могут выполняться в произвольном порядке, и поведение не определено, если binary_op не является ассоциативной. Перегрузки

(2,4,6) выполняются в соответствии с policy. Эти перегрузки не участвуют в разрешении перегрузки, если

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
policy - используемая политика выполнения. Подробнее см. политика выполнения.
init - начальное значение (необязательно)
binary_op - двоичный FunctionObject, который будет применяться к результату разыменования входных итераторов, результатам других binary_op, и init (если указано)
Требования к типу
-InputIt должно соответствовать требованиям LegacyInputIterator.
-OutputIt должно соответствовать требованиям LegacyOutputIterator.
-ForwardIt1 должно соответствовать требованиям LegacyForwardIterator.
-ForwardIt2 должно соответствовать требованиям LegacyForwardIterator.
-Если init не указано, value_type decltype(first) должен быть MoveConstructible, и binary_op(*first, *first) должно быть приводимым к типу value decltype(first).
-T (if init is provided) должно соответствовать требованиям MoveConstructible. Все binary_op(init, *first), binary_op(init, init), и binary_op(*first, *first) должны быть приводимы к T.

Возвращаемое значение

Итератор на элемент после последнего записанного элемента.

Сложность

O(last - first) применений бинарной операции.

Исключения

Перегрузки с параметром шаблона ExecutionPolicy сообщают об ошибках следующим образом:

  • Если выполнение вызываемой в рамках алгоритма функции выбрасывает исключение, а ExecutionPolicy является одной из стандартных политик, вызывается std::terminate. Для любых других ExecutionPolicy, поведение определяется реализацией.
  • Если алгоритм не может выделить память, выбрасывается std::bad_alloc

Пример

#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

См. также

adjacent_difference
вычисляет разности между соседними элементами в диапазоне
(шаблон функции)
accumulate
суммирует или складывает диапазон элементов
(шаблон функции)
partial_sum
вычисляет частичную сумму диапазона элементов
(шаблон функции)
transform_inclusive_scan
(C++17)
применяет вызываемый объект, затем вычисляет накопительную сумму с включением
(шаблон функции)
exclusive_scan
(C++17)
аналогично std::partial_sum, исключает i-й элемент входных данных из i-й суммы
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/algorithm/inclusive_scan

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API