Числовые алгоритмы: accumulate, reduce, transform_reduce
Агрегируйте числовые диапазоны с помощью accumulate, reduce и удобного для параллельного выполнения transform_reduce.
«Числовые алгоритмы: accumulate, reduce, transform_reduce» — бесплатный урок C++ Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.
Заголовок <numeric>
Числовые алгоритмы работают с диапазонами чисел. Они находятся в <numeric>.
std::accumulate
Классическое свёртывание. По умолчанию суммирует значения — для других видов свёртки передайте пользовательскую бинарную операцию.
#include <numeric>
std::vector<int> v = {1, 2, 3, 4, 5};
int sum = std::accumulate(v.begin(), v.end(), 0);
// sum = 15Пользовательское свёртывание
Укажите начальное значение и бинарную операцию.
int product = std::accumulate(v.begin(), v.end(), 1,
std::multiplies<int>{});
// product = 120Тип начального значения имеет значение
Тип аккумулятора выводится из начального значения. Укажите 0.0, чтобы накапливать значения типа double в объекте типа double.
std::vector<double> v = {1.5, 2.5, 3.5};
double sum_d = std::accumulate(v.begin(), v.end(), 0.0); // 7.5
int sum_i = std::accumulate(v.begin(), v.end(), 0); // truncates to 6std::reduce (C++17)
Похож на accumulate, но операция должна быть ассоциативной и коммутативной, что позволяет выполнять вычисления параллельно.
#include <numeric>
#include <execution>
std::vector<int> v(1000);
int sum = std::reduce(std::execution::par,
v.begin(), v.end(), 0);reduce и accumulate
Два отличия:
reduceможет выполняться параллельноreduceне гарантирует порядок выполнения операции — это подходит для + и *, но не работает для неассоциативных операций, таких как объединение строк
std::transform_reduce (C++17)
Объединяет преобразование и свёртывание за один проход. Быстрее и выразительнее, чем отдельные transform и reduce.
// Dot product
std::vector<int> a = {1, 2, 3}, b = {4, 5, 6};
int dot = std::transform_reduce(
a.begin(), a.end(), b.begin(),
0,
std::plus<int>{}, // reduce
std::multiplies<int>{} // transform
);
// dot = 1*4 + 2*5 + 3*6 = 32std::inner_product
Более старый аналог transform_reduce. Вычисляет скалярное произведение двух диапазонов. Он менее универсален, но предоставляет более простой интерфейс.
std::partial_sum
Записывает текущие накопленные суммы в выходной диапазон.
std::vector<int> v = {1, 2, 3, 4};
std::vector<int> sums(4);
std::partial_sum(v.begin(), v.end(), sums.begin());
// sums = {1, 3, 6, 10}std::adjacent_difference
Противоположность partial_sum — записывает разности между соседними элементами.
std::vector<int> v = {1, 3, 6, 10};
std::vector<int> diffs(4);
std::adjacent_difference(v.begin(), v.end(), diffs.begin());
// diffs = {1, 2, 3, 4}Особенность чисел с плавающей точкой
Для чисел с плавающей точкой порядок накопления имеет значение из-за округления. reduce может давать немного другие результаты, чем accumulate, из-за не определённого порядка вычислений.
Применение в реальных задачах
Числовые алгоритмы используются для:
- вычисления сумм и произведений
- статистических агрегатов, таких как среднее значение и дисперсия
- вычисления скалярных произведений и норм в линейной алгебре
- накопительных сумм для запросов по префиксам
Быстрая проверка
Какой алгоритм C++17 выполняет параллельное свёртывание диапазона одним вызовом функции?
Итоги
<numeric> предоставляет accumulate, reduce, transform_reduce, partial_sum и adjacent_difference для числовых свёрток и операций над префиксами. Выбирайте reduce для параллельного выполнения, а accumulate — для детерминированного порядка.
Часто задаваемые вопросы
Урок «Числовые алгоритмы: accumulate, reduce, transform_reduce» бесплатный?
Да — полный текст урока «Числовые алгоритмы: accumulate, reduce, transform_reduce» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.
Чему я научусь в уроке «Числовые алгоритмы: accumulate, reduce, transform_reduce»?
Агрегируйте числовые диапазоны с помощью accumulate, reduce и удобного для параллельного выполнения transform_reduce. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C++ Academy?
Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Числовые алгоритмы: accumulate, reduce, transform_reduce»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C++ Academy?
Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Алгоритмы без изменения: find, count, all_of
- Изменяющие алгоритмы: transform, copy_if, replace
- Сортировка и разбиение: sort, stable_partition
- Числовые алгоритмы: accumulate, reduce, transform_reduce