Ce face std::accumulate
std::accumulate (din <numeric>) pornește de la init și adaugă, de la stânga la dreapta, fiecare element: init = init + element. Cu al patrulea argument poți folosi altă operație: înmulțire, concatenare, maxim.
Tipul rezultatului este tipul lui init, nu tipul elementelor. Dacă aduni numere cu zecimale pornind de la 0 (un int), zecimalele se pierd la fiecare pas. Pornește de la 0.0.
Din C++23 există și std::ranges::fold_left(v, init, op), echivalentul pentru ranges.
Parametri
| Parametru | Descriere |
|---|---|
first, last |
Intervalul. |
init |
Valoarea de pornire; îi dă și tipul rezultatului. |
op |
Opțional. Funcție (acumulat, element) care returnează noul acumulat. |
Ce returnează
Valoarea acumulată.
Exemple
Exemplul 1: Suma și media notelor
#include <numeric>
#include <print>
#include <vector>
int main() {
std::vector<double> note{9.5, 8.0, 7.25, 10.0};
double suma = std::accumulate(note.begin(), note.end(), 0.0);
std::println("Suma: {:.2f}", suma);
std::println("Media: {:.2f}", suma / note.size());
}
Rezultat
Suma: 34.75
Media: 8.69
Exemplul 2: Capcana lui 0 în loc de 0.0
Cu 0, rezultatul este int și fiecare sumă parțială este trunchiată: 0 + 1.5 = 1, 1 + 2.5 = 3, 3 + 3.5 = 6.
#include <numeric>
#include <print>
#include <vector>
int main() {
std::vector<double> v{1.5, 2.5, 3.5};
std::println("Cu 0: {}", std::accumulate(v.begin(), v.end(), 0));
std::println("Cu 0.0: {}", std::accumulate(v.begin(), v.end(), 0.0));
}
Rezultat
Cu 0: 6
Cu 0.0: 7.5
Exemplul 3: Produs, concatenare și fold_left
#include <algorithm>
#include <functional>
#include <numeric>
#include <print>
#include <string>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3, 4, 5};
std::println("Produs: {}", std::accumulate(v.begin(), v.end(), 1, std::multiplies<>()));
std::vector<std::string> cuvinte{"Ana", "are", "mere"};
std::string fraza = std::accumulate(cuvinte.begin() + 1, cuvinte.end(), cuvinte[0],
[](std::string a, const std::string& b) { return a + " " + b; });
std::println("{}", fraza);
std::println("fold_left: {}", std::ranges::fold_left(v, 0, std::plus<>()));
}
Rezultat
Produs: 120
Ana are mere
fold_left: 15
Greșeli frecvente
- Inițializezi cu
0o sumă dedoubleși pierzi zecimalele. - Aduni mulți
intmari pornind de la0: suma depășește limita luiint. Pornește de la0LL(long long). - Uiți
#include <numeric>:accumulatenu este în<algorithm>.
Comenzi înrudite
std::reduce: Ca accumulate, dar fără ordine fixă a operațiilor, ceea ce permite calcul în paralel.std::transform_reduce: Transformă fiecare element și combină rezultatele într-o singură valoare, într-o singură trecere.std::partial_sum: Calculează sumele parțiale (cumulate): fiecare element al rezultatului este suma tuturor elementelor până la el.std::count: Numără de câte ori apare o valoare (count) sau câte elemente îndeplinesc o condiție (count_if).