std::inclusive_scan
С сайта ru.cppreference.net
| Определено в заголовке <numeric>
|
||
template< class InputIt, class OutputIt >
OutputIt inclusive_scan( InputIt first, InputIt last,
OutputIt d_first );
|
(1) | (начиная с C++17) (constexpr начиная с C++20) |
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2 >
ForwardIt2 inclusive_scan( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
|
(2) | (начиная с C++17) |
template< class InputIt, class OutputIt, class BinaryOp >
OutputIt inclusive_scan( InputIt first, InputIt last,
OutputIt d_first, BinaryOp op );
|
(3) | (начиная с C++17) (constexpr начиная с C++20) |
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2, class BinaryOp >
ForwardIt2 inclusive_scan( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, BinaryOp op );
|
(4) | (начиная с C++17) |
template< class InputIt, class OutputIt,
class BinaryOp, class T >
OutputIt inclusive_scan( InputIt first, InputIt last,
OutputIt d_first, BinaryOp op, T init );
|
(5) | (начиная с C++17) (constexpr начиная с C++20) |
template< class ExecutionPolicy,
class ForwardIt1, class ForwardIt2,
class BinaryOp, class T >
ForwardIt2 inclusive_scan( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first, BinaryOp op, T init );
|
(6) | (начиная с C++17) |
1) Эквивалентно
inclusive_scan(first, last, d_first, std::plus<>().3) Вычисляет инклюзивную префиксную сумму, используя
op. Для каждого целого числа
i в [0, std::distance(first, last)), выполняет следующие операции по порядку:
- Создаёт последовательность, образованную элементами
[first,iter]по порядку, гдеiter— это следующийi-й итератор изfirst. - Вычисляет обобщённую некоммутативную сумму последовательности над
op. - Присваивает результат в
*dest, гдеdest— это следующийi-й итератор изd_first.
5) То же, что и (3), но каждая создаваемая последовательность образована
init, за которым следуют элементы [first, iter] по порядку.2,4,6) То же, что и (1,3,5), но выполняется в соответствии с
policy. Эти перегрузки участвуют в разрешении перегрузки, только если значение следующего выражения равно
true:
|
|
(до C++20) |
|
|
(начиная с C++20) |
Обобщённая некоммутативная сумма последовательности элементов над бинарной операцией binary_op определяется следующим образом:
- Если последовательность содержит только один элемент, суммой является значение этого элемента.
- В противном случае выполняются следующие операции по порядку:
- Выбираются любые два смежных элемента
elem1иelem2из последовательности. - Вычисляется
binary_op(elem1, elem2), и два элемента в последовательности заменяются результатом. - Шаги 1 и 2 повторяются, пока в последовательности не останется только один элемент.
Дано binary_op как фактическая бинарная операция:
- Результат недетерминирован, если
binary_opне является ассоциативной (например, сложение с плавающей запятой).
- Для перегрузок (1-4), если
binary_op(*first, *first)не преобразуется в тип значенияdecltype(first), программа является некорректной.
- Для перегрузок (5,6), если любое из следующих значений не преобразуется в
T, программа является некорректной:
binary_op(init, *first)binary_op(init, init)binary_op(*first, *first)
- Если выполняется любое из следующих условий, поведение не определено:
- Для перегрузок (1-4), тип значения
decltype(first)не является MoveConstructible. - Для перегрузок (5,6),
Tне является MoveConstructible. binary_opизменяет любой элемент[first,last).binary_opделает недействительным любой итератор или поддиапазон[first,last].
- Для перегрузок (1-4), тип значения
Параметры
| first, last | - | пара итераторов, определяющая исходный диапазон элементов для суммирования |
| d_first | - | начало целевого диапазона; может быть равно first
|
| policy | - | политика выполнения для использования |
| init | - | начальное значение |
| op | - | бинарный FunctionObject, который будет применяться к результату разыменования входных итераторов, результатам других op и init (если предоставлено)
|
| Требования к типам | ||
-InputIt должен соответствовать требованиям LegacyInputIterator.
| ||
-OutputIt должен соответствовать требованиям LegacyOutputIterator.
| ||
-ForwardIt1, ForwardIt2 должен соответствовать требованиям LegacyForwardIterator.
| ||
Возвращаемое значение
Итератор на элемент, следующий за последним записанным элементом.
Сложность
Пусть N равно std::distance(first, last):
1,2) O(N) применений
std::plus<>().3-6) O(N) применений
op.Исключения
Перегрузки с параметром шаблона с именем 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
Смотрите также
| вычисляет разности между соседними элементами в диапазоне (шаблон функции) | |
| суммирует или свёртывает диапазон элементов (шаблон функции) | |
| вычисляет частичную сумму диапазона элементов (шаблон функции) | |
(C++17) |
применяет вызываемый объект, затем вычисляет инклюзивную сканирующую сумму (шаблон функции) |
(C++17) |
аналогично std::partial_sum, исключает i-й входной элемент из i-й суммы (шаблон функции) |