Los algoritmos de la STL en C++ se clasifican en varias categorías según su efecto sobre los datos. A continuación se presentan ejemplos prácticos con implementaciones modificadas para reducir el consumo energético en sistemas embebidos, aunque los principios algorítmicos son los mismos.
1. Algoritmos de solo lectura
No alteran el contenedor original.
1.1 find y find_if
localizan un elemento o el primero que cumple una condición.
std::list<int> datos = {8, 2, 6, 4, 10};
auto pos = std::find(datos.begin(), datos.end(), 6);
if (pos != datos.end()) {
// valor 6 encontrado
}
auto posPar = std::find_if(datos.begin(), datos.end(),
[](int x) { return x % 2 == 0; });
// primer par: 8
std::vector<int> sub = {2, 6};
auto finSub = std::find_end(datos.begin(), datos.end(),
sub.begin(), sub.end());
// índice de la última aparición de {2,6}
1.2 count y count_if
Cuentan ocurrencias.
std::array<int,6> arr = {1,2,2,3,2,4};
int cuantos2 = std::count(arr.begin(), arr.end(), 2); // 3
int cuantosPares = std::count_if(arr.begin(), arr.end(),
[](int x) { return x%2==0; }); // 4
1.3 for_each
Ejecuta una función sobre cada elemento (puede modificar si se pasa referencia).
std::deque<int> sec = {1,2,3,4};
std::for_each(sec.begin(), sec.end(), [](int &v) { v *= 2; });
// sec = {2,4,6,8}
1.4 equal y mismatch
Comparan rangos.
std::vector<int> a = {1,2,3};
std::vector<int> b = {1,2,4};
bool igual = std::equal(a.begin(), a.end(), b.begin()); // false
auto dif = std::mismatch(a.begin(), a.end(), b.begin());
// dif.first apunta a 3, dif.second a 4
1.5 all_of, any_of, none_of
std::vector<int> col = {2,4,6,8};
bool todosPares = std::all_of(col.begin(), col.end(),
[](int x) { return x%2==0; }); // true
bool algunImpar = std::any_of(...); // false
bool ningunNeg = std::none_of(...); // true
2. Algoritmos que modifican secuencias
2.1 copy y copy_if
std::vector<int> fuente = {1,2,3,4,5};
std::vector<int> destino(5);
std::copy(fuente.begin(), fuente.end(), destino.begin());
std::vector<int> pares;
std::copy_if(fuente.begin(), fuente.end(),
std::back_inserter(pares), [](int x) { return x%2==0; });
// pares = {2,4}
2.2 transform
std::vector<int> entrada = {1,2,3};
std::vector<int> cuadrados(3);
std::transform(entrada.begin(), entrada.end(), cuadrados.begin(),
[](int x) { return x*x; });
std::vector<int> v1 = {1,2,3}, v2 = {4,5,6}, suma(3);
std::transform(v1.begin(), v1.end(), v2.begin(), suma.begin(),
std::plus<int>());
2.3 replace, replace_if, replace_copy
std::vector<int> nums = {1,2,3,2,5};
std::replace(nums.begin(), nums.end(), 2, 20); // {1,20,3,20,5}
std::replace_if(nums.begin(), nums.end(),
[](int x) { return x>10; }, 0); // {1,0,3,0,5}
std::vector<int> copia;
std::replace_copy(nums.begin(), nums.end(),
std::back_inserter(copia), 3, 300);
// copia = {1,0,300,0,5}
2.4 remove, remove_if y erase (borrado lógico y físico)
std::vector<int> datos = {1,2,3,2,4};
auto nuevoFinal = std::remove(datos.begin(), datos.end(), 2);
datos.erase(nuevoFinal, datos.end()); // {1,3,4}
datos = {1,2,3,4,5};
datos.erase(std::remove_if(datos.begin(), datos.end(),
[](int x) { return x%2==0; }),
datos.end()); // {1,3,5}
2.5 unique
std::vector<int> rep = {1,1,2,2,3,3,3,4,5};
auto it = std::unique(rep.begin(), rep.end());
rep.erase(it, rep.end()); // {1,2,3,4,5}
2.6 reverse
std::list<int> lst = {1,2,3,4,5};
std::reverse(lst.begin(), lst.end()); // {5,4,3,2,1}
2.7 rotate
std::vector<int> v = {1,2,3,4,5};
std::rotate(v.begin(), v.begin()+2, v.end());
// {3,4,5,1,2}
2.8 shuffle
#include <random>
std::vector<int> v = {1,2,3,4,5};
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(v.begin(), v.end(), g);
3. Algoritmos de ordenación y búsqueda binaria
3.1 sort, stable_sort, partial_sort
std::vector<int> v = {5,3,1,4,2};
std::sort(v.begin(), v.end()); // asc
std::sort(v.begin(), v.end(), std::greater<int>()); // desc
std::vector<std::pair<int,int>> par = {{1,2},{2,1},{1,1},{2,2}};
std::stable_sort(par.begin(), par.end(),
[](const auto &a, const auto &b) { return a.first < b.first; });
std::vector<int> v2 = {5,3,1,4,2,6};
std::partial_sort(v2.begin(), v2.begin()+3, v2.end());
// primeros 3: 1,2,3
3.2 nth_element
std::vector<int> v = {5,3,1,4,2,6};
std::nth_element(v.begin(), v.begin()+2, v.end());
// v[2] = 3, izquierda ≤3, derecha ≥3
3.3 binary_search, lower_bound, upper_bound
std::vector<int> ord = {1,3,3,5,7};
bool existe = std::binary_search(ord.begin(), ord.end(), 3); // true
auto lb = std::lower_bound(ord.begin(), ord.end(), 3); // índice 1
auto ub = std::upper_bound(ord.begin(), ord.end(), 3); // índice 3
3.4 merge
std::vector<int> a = {1,3,5}, b = {2,4,6};
std::vector<int> fusion(6);
std::merge(a.begin(), a.end(), b.begin(), b.end(), fusion.begin());
// {1,2,3,4,5,6}
4. Algoritmos de montículo (heap)
std::vector<int> h = {4,1,3,2,5};
std::make_heap(h.begin(), h.end()); // max-heap
h.push_back(6);
std::push_heap(h.begin(), h.end());
std::pop_heap(h.begin(), h.end());
int max = h.back(); h.pop_back();
std::sort_heap(h.begin(), h.end()); // asc
5. Mínimos y máximos
int minVal = std::min(5,3); // 3
int maxVal = std::max({4,2,8,5,1}); // 8
std::vector<int> v = {3,1,4,2,5};
auto minIt = std::min_element(v.begin(), v.end()); // apunta a 1
auto maxIt = std::max_element(v.begin(), v.end()); // apunta a 5
auto mm = std::minmax_element(v.begin(), v.end());
// mm.first → 1, mm.second → 5
6. Algoritmos numéricos (<numeric>)
6.1 accumulate
#include <numeric>
std::vector<int> v = {1,2,3,4,5};
int suma = std::accumulate(v.begin(), v.end(), 0); // 15
int prod = std::accumulate(v.begin(), v.end(), 1,
std::multiplies<int>()); // 120
6.2 inner_product
std::vector<int> a={1,2,3}, b={4,5,6};
int dot = std::inner_product(a.begin(),a.end(),b.begin(),0); // 32
6.3 iota
std::vector<int> v(5);
std::iota(v.begin(), v.end(), 10); // {10,11,12,13,14}
6.4 partial_sum
std::vector<int> src={1,2,3,4,5}, dst(5);
std::partial_sum(src.begin(), src.end(), dst.begin()); // {1,3,6,10,15}
6.5 adjacent_difference
std::adjacent_difference(src.begin(), src.end(), dst.begin()); // {1,1,1,1,1}
7. Algoritmos adicionales
7.1 generate y generate_n
std::vector<int> v(5);
int n = 0;
std::generate(v.begin(), v.end(), [&n]() { return n++; }); // {0,1,2,3,4}
std::vector<int> w(5);
n = 10;
std::generate_n(w.begin(), 3, [&n]() { return n++; }); // {10,11,12,?,?}
7.2 includes
std::vector<int> v1={1,2,3,4,5}, v2={2,4};
bool ok = std::includes(v1.begin(),v1.end(),v2.begin(),v2.end()); // true
7.3 Operaciones de conjunto (en ordenación previa)
std::vector<int> v1={1,2,3,4,5}, v2={3,4,5,6,7}, res;
std::set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),
std::back_inserter(res)); // {1,2,3,4,5,6,7}
res.clear();
std::set_intersection(...); // {3,4,5}
res.clear();
std::set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),
std::back_inserter(res)); // {1,2}
res.clear();
std::set_symmetric_difference(...); // {1,2,6,7}
8. Notas prácticas en sistemas embebidos
sortusa introsort (inestable) ystable_sortmergesort (estable, mayor consumo de memoria). Preferirsortsi el orden relativo no importa.removeno reduce el tamaño del contenedor; debe combinarse conerasepara liberar memoria. En sistemas con poca RAM, usarerasepuede caussar reubicaciones costosas.- Algoritmos como
binary_searchyset_intersectionrequieren datos ordenados. Ordenar una vez y reutilizar reduce el consumo energético. - En microcontroladores sin excepciones ni RTTI, usar
std::vectorcon precaución; a veces es mejor buffers estáticos.