Lección 12 · 12 de 20
Algoritmos de la STL · C++
Procese datos en C++ con transform, accumulate, count_if, find_if y remove_if con erase: las ventas de una tienda sin escribir bucles.

Las cabeceras <algorithm> y <numeric> traen decenas de algoritmos que trabajan sobre un rango, de begin() a end(). Con lambdas, sustituyen a muchos bucles y dejan claro de un vistazo qué hace cada línea.
`remove_if` no borra nada: mueve al final los elementos que cumplen la condición (aquí la devolución, con importe negativo) y devuelve dónde empiezan. `erase` recorta desde ahí hasta el final. Las dos juntas forman el modismo *erase-remove*; si se olvida la segunda, el vector conserva su tamaño.
`transform` calcula un valor nuevo por cada elemento y lo escribe en otro rango: withVat se crea con el tamaño justo y recibe cada precio con el 21 % de IVA. El ratón, tercero de la lista tras quitar la devolución, pasa de 19,50 a 23,595.
`accumulate` reduce todo a un valor, empezando por el tercer argumento. Escriba 0.0 y no 0: con un entero, la suma se haría con enteros y perdería los decimales. Con una lambda suma el campo amount de cada venta; sin ella, suma directamente los double de withVat.
`count_if` cuenta los elementos que cumplen una condición (dos ventas de 100 euros o más) y `find_if` devuelve un iterador al primero que la cumple, o end() si no hay ninguno; por eso se compara con sales.end() antes de usar cheap->product.
Código · main.cpp
#include <algorithm>#include <iostream>#include <numeric>#include <string>#include <vector>struct Sale { std::string product; double amount; };int main() { std::vector<Sale> sales = {{"Keyboard", 45}, {"Monitor", 189}, {"Refund", -45}, {"Mouse", 19.5}, {"Laptop", 899}, {"Cable", 7.5}}; // remove_if moves the unwanted items to the end; erase cuts them off. auto isRefund = [](const Sale& s) { return s.amount < 0; }; sales.erase(std::remove_if(sales.begin(), sales.end(), isRefund), sales.end()); // transform: one new value per element (the price with 21% VAT). std::vector<double> withVat(sales.size()); std::transform(sales.begin(), sales.end(), withVat.begin(), [](const Sale& s) { return s.amount * 1.21; }); // accumulate: folds every element into one value, starting from 0.0. double net = std::accumulate(sales.begin(), sales.end(), 0.0, [](double sum, const Sale& s) { return sum + s.amount; }); double gross = std::accumulate(withVat.begin(), withVat.end(), 0.0); auto big = std::count_if(sales.begin(), sales.end(), [](const Sale& s) { return s.amount >= 100; }); auto cheap = std::find_if(sales.begin(), sales.end(), [](const Sale& s) { return s.amount < 10; }); std::cout << "Sales kept: " << sales.size() << " (first: " << sales.front().product << ")\n"; std::cout << "Mouse with VAT: " << withVat[2] << " EUR\n"; std::cout << "Net: " << net << " EUR, with VAT: " << gross << " EUR\n"; std::cout << "Sales of 100 EUR or more: " << big << "\n"; if (cheap != sales.end()) std::cout << "First under 10 EUR: " << cheap->product << "\n";}Salida · c++ -std=c++17 main.cpp -o main && ./main
Sales kept: 5 (first: Keyboard) Mouse with VAT: 23.595 EUR Net: 1160 EUR, with VAT: 1403.6 EUR Sales of 100 EUR or more: 2 First under 10 EUR: Cable
Para recordar
- Los algoritmos reciben un rango:
v.begin(), v.end(). remove_if+eraseborran de verdad los elementos que cumplen una condición.transformcalcula un valor nuevo por elemento.accumulate(b, e, 0.0)suma; el tipo del valor inicial manda.find_ifdevuelveend()si no encuentra nada: compruébelo antes de usarlo.
Ejercicio
Use std::max_element con una lambda para encontrar la venta más alta y escriba su producto y su importe. Después, cuente con count_if las ventas de menos de 50 euros.