0Pricing
C++ Academy · Урок

Числовые алгоритмы: 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 6

std::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 = 32

std::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 — локальная установка не требуется.

Все уроки этого курса

  1. Алгоритмы без изменения: find, count, all_of
  2. Изменяющие алгоритмы: transform, copy_if, replace
  3. Сортировка и разбиение: sort, stable_partition
  4. Числовые алгоритмы: accumulate, reduce, transform_reduce
← Назад к C++ Academy