Saltar al contenido
Portada » Lenguajes » 13. Bibliotecas Estándar y Utilidades en C++

13. Bibliotecas Estándar y Utilidades en C++

Bibliotecas Estándar y Utilidades en C++. Una de los aspectos destacables de C++ radica en su Biblioteca Estándar (Standard Library), que incluye un conjunto muy completo de herramientas, algoritmos y estructuras de datos ya implementadas para hacer uso de ellas. Dentro de esta biblioteca destaca la STL (Standard Template Library), un conjunto de clases y funciones genéricas que permiten trabajar con colecciones de datos (contenedores), recorrerlas (iteradores), y transformarlas o consultarlas.

Este capítulo se centrará en hacer una introducción a las principales estructuras de datos y utilidades que ofrece STL, junto con otras herramientas como:

  • Vectores y listas, como estructuras dinámicas para almacenar elementos.
  • Conjuntos y mapas, para manejar datos únicos o pares clave-valor.
  • Iteradores, para recorrer contenedores.
  • Algoritmos estándar, como sort, find, count, entre muchos otros.
  • Funciones lambda, introducida en C++ Versión 11 que permite definir funciones anónimas.

El objetivo de este capítulo es brindarte una pequeña base en el uso de estas herramientas que te permitirán escribir código más agilmente.

13.1 STL (Standard Template Library)

La STL (Standard Template Library) es una parte fundamental de la biblioteca estándar de C++. Proporciona un conjunto de clases y funciones genéricas que permiten manipular colecciones de datos de manera eficiente, flexible y reutilizable.

Fue diseñada para ser altamente modular, aprovechando las capacidades de las plantillas (templates), lo que significa que puedes usar los mismos algoritmos y estructuras con diferentes tipos de datos.

Componentes principales de la STL

La STL se compone principalmente de tres grandes bloques:

ComponenteDescripciónEjemplos
ContenedoresEstructuras de datos que almacenan objetos.vector, list, set, map, deque, etc.
AlgoritmosFunciones genéricas para procesar los datos de los contenedores.sort, find, count, reverse, etc.
IteradoresObjetos que permiten recorrer los elementos de un contenedor.begin(), end(), ++, *, etc.

A estos se les puede sumar:

  • Funciones lambda: funciones anónimas y cortas para ser usadas con algoritmos.
  • Functores: objetos que actúan como funciones (menos usados hoy en día gracias a las lambdas).
  • Adaptadores: transforman la interfaz de un contenedor o función (como stack, queue, priority_queue).

A continuación, veamos un pequeño ejemplo que usa un vector (contenedor), un algoritmo (sort), e iteradores:

#include <iostream>
#include <vector>
#include <algorithm> // sort

int main() {
std::vector<int> numeros = {5, 2, 9, 1, 3};

std::sort(numeros.begin(), numeros.end()); // Ordena el vector de menor a mayor

std::cout << "Vector ordenado: ";
for (auto it = numeros.begin(); it != numeros.end(); ++it) {
std::cout << *it << " ";
}

return 0;
}

¿Qué tenemos aquí?

  • std::vector<int>: crea un vector de enteros.
  • std::sort: algoritmo que ordena los elementos del vector.
  • begin() y end(): devuelven iteradores al inicio y fin del contenedor.
  • auto it: deduce automáticamente el tipo del iterador.

13.2 Vectores (std::vector)

¿Qué es un std::vector?

std::vector es una de las estructuras de datos más utilizadas de la STL. Es un contenedor secuencial que permite almacenar un conjunto de elementos del mismo tipo, con la capacidad de redimensionarse automáticamente cuando se añaden o eliminan elementos.

Podemos pensar en un vector como un array dinámico que:

  • puede crecer o reducir su tamaño durante la ejecución,
  • gestiona automáticamente la memoria,
  • proporciona funciones útiles para insertar, eliminar, acceder y recorrer elementos.

Sintaxis

#include <vector>
std::vector<Tipo> nombre_vector;

Ejemplo:

std::vector<int> numeros;  // Vector vacío de enteros
std::vector<std::string> nombres(3); // Vector de 3 strings vacíos
std::vector<float> precios = {10.5, 3.99, 7.25}; // Inicialización con valores

Operaciones principales

  • Agregar elementos
numeros.push_back(10);  // Agrega un elemento al final
  • Acceder a elementos
int x = numeros[0];        // Acceso sin verificación de rango
int y = numeros.at(1); // Acceso con verificación de rango (lanza excepción si se sale)
  • Obtener tamaño
int tam = numeros.size();
  • Eliminar el último elemento
numeros.pop_back();
  • Vaciar el vector
numeros.clear();
  • Recorrer con bucle tradicional
for (size_t i = 0; i < numeros.size(); i++) {
std::cout << numeros[i] << std::endl;
}
  • Recorrer con bucle basado en rango (C++11)
for (int n : numeros) {
std::cout << n << std::endl;
}
  • Con iteradores
for (auto it = numeros.begin(); it != numeros.end(); ++it) {
std::cout << *it << std::endl;
}

Veamos un ejemplo práctico

#include <iostream>
#include <vector>

int main() {
std::vector<int> edades;

edades.push_back(25);
edades.push_back(30);
edades.push_back(18);

std::cout << "Edades ingresadas: ";
for (int edad : edades) {
std::cout << edad << " ";
}

edades.pop_back(); // Elimina el último elemento

std::cout << "\nDespués de eliminar la última edad: ";
for (size_t i = 0; i < edades.size(); i++) {
std::cout << edades[i] << " ";
}

return 0;
}

Salida esperada:

Edades ingresadas: 25 30 18 
Después de eliminar la última edad: 25 30

Ventajas de std::vector frente a arrays tradicionales

std::vectorArray tradicional
Tamaño dinámicoTamaño fijo
Métodos útiles (push_back, size, etc.)No posee métodos
Mejor manejo de memoriaEl programador debe gestionar memoria dinámica
Compatible con algoritmos STLUso limitado con algoritmos

Inicialización avanzada

std::vector<int> v1(5);            // 5 elementos inicializados a 0
std::vector<int> v2(5, 100); // 5 elementos inicializados a 100
std::vector<int> v3 = {1, 2, 3}; // Lista de inicialización (C++11)

Tabla de operaciones con std::vector

OperaciónDescripciónEjemplo de uso
push_back(valor)Añade un elemento al final del vectorv.push_back(10);
pop_back()Elimina el último elemento del vectorv.pop_back();
size()Devuelve el número de elementos del vectorint n = v.size();
empty()Devuelve true si el vector está vacíoif (v.empty()) { ... }
clear()Elimina todos los elementos del vectorv.clear();
at(pos)Devuelve el elemento en la posición pos con verificaciónint x = v.at(1);
operator[]Devuelve el elemento en la posición pos sin verificaciónint x = v[1];
front()Devuelve el primer elementoint x = v.front();
back()Devuelve el último elementoint x = v.back();
insert(pos, valor)Inserta valor en la posición pos (como iterador)v.insert(v.begin() + 2, 99);
erase(pos)Elimina el elemento en la posición pos (como iterador)v.erase(v.begin() + 1);
begin()Devuelve un iterador al inicio del vectorauto it = v.begin();
end()Devuelve un iterador al final (uno después del último)auto it = v.end();
assign(n, valor)Asigna n elementos con el valor indicadov.assign(5, 100);
resize(n)Cambia el tamaño del vector a n elementosv.resize(10);
swap(v2)Intercambia los contenidos con otro vector v2v.swap(v2);
capacity()Muestra la capacidad interna del vectorsize_t cap = v.capacity();
shrink_to_fit()Reduce la capacidad para igualar el tamaño realv.shrink_to_fit();
data()Devuelve puntero al bloque de memoria del primer elementoint* ptr = v.data();

13.3 Listas (std::list)

¿Qué es std::list?

std::list es una estructura de datos de la Biblioteca Estándar de C++ que representa una lista doblemente enlazada. A diferencia de un std::vector, que almacena sus elementos contiguamente en memoria, una lista enlazada está formada por nodos que contienen los datos y punteros a los nodos anterior y siguiente.

Esto implica que:

  • La inserción y eliminación de elementos en cualquier parte de la lista es muy eficiente (constante, O(1)), porque solo implica cambiar punteros.
  • El acceso aleatorio (acceder directamente a un elemento por índice) es lento (lineal, O(n)) porque hay que recorrer la lista desde el principio o el final.
  • Es ideal para escenarios donde se hacen muchas inserciones y borrados en medio de la colección.

Declaración básica

#include <list>

std::list<int> miLista;

Para el manejo de listas, hay que tener unas consideraciones en cuenta:

  • Los elementos se almacenan en nodos enlazados.
  • No hay acceso por índice (operator[] no está definido).
  • Se puede recorrer con iteradores.
  • Permite inserciones y eliminaciones eficientes en cualquier posición.

¿Qué operaciones se pueden realizar?

Para el manejo de listas nos apoyamos en un conjunto de funciones que nos facilitan la labor del manejo de los elementos de la lista. Veamoslos en una tabla.

OperaciónDescripciónEjemplo
push_back(valor)Inserta al finalmiLista.push_back(10);
push_front(valor)Inserta al principiomiLista.push_front(5);
pop_back()Elimina el último elementomiLista.pop_back();
pop_front()Elimina el primer elementomiLista.pop_front();
insert(pos, valor)Inserta antes de la posición indicada (iterador)auto it = miLista.begin(); miLista.insert(it, 7);
erase(pos)Elimina el elemento en la posición indicada (iterador)auto it = miLista.begin(); miLista.erase(it);
size()Devuelve el número de elementossize_t n = miLista.size();
empty()Comprueba si la lista está vacíaif (miLista.empty()) { ... }
clear()Elimina todos los elementosmiLista.clear();
begin()Devuelve iterador al primer elementoauto it = miLista.begin();
end()Devuelve iterador al final (no apunta a un elemento válido)auto it = miLista.end();
front()Devuelve el primer elementoint x = miLista.front();
back()Devuelve el último elementoint x = miLista.back();
remove(valor)Elimina todos los elementos que coincidan con valormiLista.remove(10);
sort()Ordena la lista (requiere elementos comparables)miLista.sort();
reverse()Invierte el orden de los elementosmiLista.reverse();

Ejemplo práctico de uso de std::list

#include <iostream>
#include <list>

int main() {
std::list<int> numeros;

// Insertar elementos
numeros.push_back(10);
numeros.push_front(5);
numeros.push_back(20);

// Recorrer la lista
std::cout << "Elementos en la lista: ";
for (int n : numeros) {
std::cout << n << " ";
}
std::cout << std::endl;

// Insertar en posición específica
auto it = numeros.begin();
++it; // Apunta al segundo elemento
numeros.insert(it, 15);

// Eliminar un elemento (el primero)
numeros.pop_front();

// Mostrar contenido tras cambios
std::cout << "Lista tras inserción y eliminación: ";
for (auto elem : numeros) {
std::cout << elem << " ";
}
std::cout << std::endl;

return 0;
}

Salida:

Elementos en la lista: 5 10 20 
Lista tras inserción y eliminación: 15 10 20

Consideraciones

  • Si necesitas acceso rápido por índice, std::vector es mejor.
  • Para inserciones/borrados frecuentes en medio de la colección, std::list es más eficiente.
  • El uso de iteradores es fundamental para trabajar con listas.

13.4 Conjuntos y Mapas (std::set, std::map)

Tanto los conjuntos (std::set) como los mapas (std::map) forman parte de la STL (Standard Template Library) de C++, y se basan internamente en estructuras de árboles binarios balanceados (como árboles rojo-negro). Esto les permite mantener los elementos ordenados y realizar búsquedas, inserciones y eliminaciones edeforma muy rápida, el tiempo de acceso en estas estructuras viene determinada por el tiempo logarítmico (O(log n)).

std::set

Un std::set es una colección de elementos únicos ordenados automáticamente. No permite duplicados, y los elementos se almacenan siguiendo una ordenación natural (por defecto, de menor a mayor).

Declaración:

#include <set>

std::set<int> conjunto;

Operaciones comunes con std::set

El conjunto de operaciones que podemos realizar sobre los conjuntos te los muestro en la siguiente tabla:

OperaciónDescripciónEjemplo
insert(valor)Inserta un nuevo elementoconjunto.insert(5);
erase(valor)Elimina un elemento (si existe)conjunto.erase(5);
find(valor)Devuelve iterador al elemento, o end() si no se encuentraauto it = conjunto.find(5);
count(valor)Devuelve 1 si el valor existe, 0 si noif (conjunto.count(5)) {...}
begin() / end()Iteradores para recorrer el conjuntofor (int x : conjunto) { ... }

Veamos un ejemplo de como se usan:

#include <iostream>
#include <set>

int main() {
std::set<int> numeros = {3, 1, 4, 1, 2, 5};

numeros.insert(6);
numeros.erase(1);

std::cout << "Contenido del set: ";
for (int n : numeros)
std::cout << n << " ";

return 0;
}

Salida:

Contenido del set: 2 3 4 5 6

Algunos de los usos donde se hace indicado utilizar conjuntos podrían ser:

  1. Almacenar una colección de elementos únicos.
  2. Eliminar duplicados de un conjunto de datos.
  3. Mantener elementos ordenados automáticamente.
  4. Buscar rápidamente si un elemento existe en una colección.
  5. Resolver problemas de teoría de conjuntos (intersección, unión, diferencia).
  6. Implementar algoritmos de grafos (nodos visitados).
  7. Gestionar horarios o eventos sin duplicados.
  8. Filtrar datos en tiempo real con eliminación automática de duplicados.

std::map

Un std::map es una colección de pares clave-valor. Las claves son únicas y se ordenan automáticamente. Cada clave se asocia a un único valor.

Declaración

#include <map>

std::map<std::string, int> edades;

Operaciones comunes con std::map

OperaciónDescripciónEjemplo
map[key] = valorInserta o modifica el valor asociado a la claveedades["Ana"] = 30;
insert({clave, valor})Inserta par clave-valor si la clave no existeedades.insert({"Luis", 25});
erase(clave)Elimina la clave y su valor asociadoedades.erase("Luis");
find(clave)Devuelve iterador a la clave, o end() si no estáauto it = edades.find("Ana");
count(clave)Retorna 1 si la clave existe, 0 si noif (edades.count("Ana")) {...}
begin() / end()Iteradores para recorrer el mapafor (auto p : edades) {...}

Veamos un ejemplo:

#include <iostream>
#include <map>

int main() {
std::map<std::string, int> edades;

edades["Juan"] = 25;
edades["María"] = 30;
edades["Carlos"] = 28;

for (auto par : edades) {
std::cout << par.first << ": " << par.second << std::endl;
}

return 0;
}

Salida:

Carlos: 28
Juan: 25
María: 30

Podemos utilizar std::map en casos como:

  1. Asociar claves con valores (por ejemplo, nombre → edad).
  2. Implementar diccionarios o tablas de símbolos.
  3. Contar la frecuencia de elementos (por ejemplo, conteo de palabras).
  4. Almacenar configuraciones o parámetros con nombres descriptivos.
  5. Indexar datos con claves no numéricas (por ejemplo, strings).
  6. Crear índices invertidos (clave: palabra, valor: lista de posiciones).
  7. Resolver problemas de programación competitiva (par clave-valor).
  8. Representar grafos mediante listas de adyacencia (nodo → vecinos).

Diferencias clave entre std::set y std::map

Característicastd::setstd::map
Tipo de datosSolo valoresPares clave-valor
ClavesEl valor es la claveLas claves son independientes del valor
Acceso por claveNoSí (map[clave])
DuplicadosNoNo (claves únicas)
Orden automático

13.5 iteradores en C++

Los iteradores son objetos que actúan como punteros que nos permiten recorrer los elementos de un contenedor de la libería STL (como vector, list, set, map, etc.) de una forma sencilla y segura. Proveen una manera estándar de acceder secuencialmente a los elementos sin conocer la implementación interna del contenedor.

Podemos pensar en ellos como «punteros inteligentes» que se usan para iterar sobre estructuras de datos.

Tipos de iteradores

C++ define varios tipos de iteradores, dependiendo del contenedor y de las operaciones permitidas:

Tipo de IteradorDescripción
input_iteratorSólo lectura hacia adelante.
output_iteratorSólo escritura hacia adelante.
forward_iteratorLectura/escritura hacia adelante.
bidirectional_iteratorLectura/escritura hacia adelante y atrás.
random_access_iteratorAcceso directo a cualquier posición (como en vector).

Sintaxis básica de iteradores

Ejemplo con std::vector:

#include <iostream>
#include <vector>

int main() {
std::vector<int> numeros = {10, 20, 30, 40};

// Usando un iterador
std::vector<int>::iterator it;

for (it = numeros.begin(); it != numeros.end(); ++it) {
std::cout << *it << " ";
}

return 0;
}

Salida:

10 20 30 40

Iteradores constantes (const_iterator)

Cuando no queremos modificar los elementos del contenedor:

std::vector<int>::const_iterator it;

for (it = numeros.cbegin(); it != numeros.cend(); ++it) {
std::cout << *it << std::endl;
}

Iteradores inversos (rbegin, rend)

Permiten recorrer los elementos en orden inverso:

for (std::vector<int>::reverse_iterator rit = numeros.rbegin(); rit != numeros.rend(); ++rit) {
std::cout << *rit << " ";
}

Salida:

40 30 20 10

Iteradores automáticos (auto)

Desde C++11, se puede usar auto para simplificar el código:

for (auto it = numeros.begin(); it != numeros.end(); ++it) {
std::cout << *it << " ";
}

Iteradores en otros contenedores

Con std::map:

std::map<std::string, int> edades = {
{"Ana", 30},
{"Luis", 25},
{"Carlos", 40}
};

for (auto it = edades.begin(); it != edades.end(); ++it) {
std::cout << it->first << " tiene " << it->second << " años.\n";
}

13.6 Algoritmos útiles de la librería standar STL

La librería estandar STL (Standard Template Library) de C++ incluye una serie de algoritmos genéricos que nos facilitan la labor de desarrollo al traerlos ya incorporados. Estos algoritmos se encuentran en el encabezado <algorithm>, y nos permiten realizar tareas como búsqueda, ordenación, copia, eliminación, transformación y más, sin necesidad de escribir el código desde cero.

Vamos a hacer un breve repaso sobre los más útiles y utilizados

  • std::sort

Ordena los elementos, por defecto en orden ascendente.

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
std::vector<int> numeros = {5, 2, 9, 1};

std::sort(numeros.begin(), numeros.end());

for (int n : numeros)
std::cout << n << " ";
}

Salida:

1 2 5 9

🔁También se puede usar un comparador personalizado:

std::sort(numeros.begin(), numeros.end(), std::greater<int>());

Esto los ordena en orden descendente.

  • std::find

Busca un valor en el contenedor y devuelve un iterador a él (o end() si no se encuentra).

it = std::find(numeros.begin(), numeros.end(), 5);
if (it != numeros.end()) {
std::cout << "Encontrado: " << *it << "\n";
}
  • std::count

Cuenta cuántas veces aparece un valor específico en el contenedor.

int veces = std::count(numeros.begin(), numeros.end(), 5);
std::cout << "El número 5 aparece " << veces << " veces\n";
  • std::reverse

Invierte el orden de los elementos de un contenedor.

std::reverse(numeros.begin(), numeros.end());
  • std::for_each

Aplica una función o lambda a cada elemento de un contenedor.

std::for_each(numeros.begin(), numeros.end(), [](int n) {
std::cout << n * 2 << " ";
});
  • std::remove y std::erase

Elimina elementos de un contenedor. En vector, se suele usar con erase:

numeros.erase(std::remove(numeros.begin(), numeros.end(), 2), numeros.end());
  • std::accumulate (requiere <numeric>)

Suma todos los elementos (u otra operación acumulativa).

#include <numeric>
int suma = std::accumulate(numeros.begin(), numeros.end(), 0);
  • std::sort con estructuras personalizadas
struct Persona {
std::string nombre;
int edad;
};

std::vector<Persona> personas = {
{"Ana", 30},
{"Luis", 25},
{"Carlos", 35}
};

std::sort(personas.begin(), personas.end(), [](const Persona &a, const Persona &b) {
return a.edad < b.edad;
});

13.7. Funciones Lambda

Las funciones lambda son una característica introducida en C++11 que permite definir funciones anónimas (es decir, sin nombre) directamente en línea, generalmente para pasarlas como argumento a algoritmos o funciones.

Son especialmente útiles cuando queremos definir comportamientos cortos y específicos, por ejemplo, para ordenar, filtrar o aplicar una operación rápida sin necesidad de crear una función aparte.

Sintaxis:

[captura](parámetros) -> tipo_retorno {
// cuerpo
}
  • [captura]: define qué variables externas puede usar la lambda.
  • (parámetros): los argumentos de la función.
  • -> tipo_retorno (opcional): especifica el tipo de retorno.
  • { ... }: cuerpo de la lambda.

En la mayoría de casos, el compilador puede deducir el tipo de retorno automáticamente, por lo que suele omitirse.

Ejemplo:

#include <iostream>

int main() {
auto cuadrado = [](int x) {
return x * x;
};

std::cout << "El cuadrado de 5 es: " << cuadrado(5) << "\n";
}

Usos con algoritmos de STL

Las lambdas se utilizan mucho con algoritmos como sort, for_each, find_if, etc.

  • Ordenar con lambda:
#include <vector>
#include <algorithm>
#include <iostream>

int main() {
std::vector<int> v = {5, 2, 9, 1};

std::sort(v.begin(), v.end(), [](int a, int b) {
return a > b; // Orden descendente
});

for (int n : v)
std::cout << n << " ";
}
  • for_each con lambda:
std::for_each(v.begin(), v.end(), [](int n) {
std::cout << "Elemento: " << n << "\n";
});
  • Captura de variables

Una lambda puede capturar variables externas (del ámbito en el que está definida) de varias formas:

CapturaSignificado
[ ]No captura nada
[=]Captura todas las variables por valor
[&]Captura todas las variables por referencia
[x]Captura x por valor
[&x]Captura x por referencia
[=, &x]Todo por valor, excepto x por referencia

Veamos un ejemplo de captura por valor:

int factor = 2;
auto multiplicar = [factor](int x) {
return x * factor;
};
std::cout << multiplicar(3); // Imprime 6

Y ahora un ejemplo de captura por referencia:

int total = 0;
std::vector<int> v = {1, 2, 3};

std::for_each(v.begin(), v.end(), [&total](int n) {
total += n;
});
std::cout << "Suma total: " << total;

Ventajas de las lambdas

  • Código más conciso y legible.
  • Evita escribir funciones auxiliares innecesarias.
  • Permite usar lógica en línea.
  • Muy potentes con algoritmos STL.

Conclusión

En este capítulo exploramos la STL (Standard Template Library) de C++, que ofrece estructuras de datos y algoritmos listos para usar. Vimos:

  • std::vector: arrays dinámicos que permiten acceso rápido y redimensionamiento automático.
  • std::list: listas doblemente enlazadas útiles para inserciones y eliminaciones frecuentes.
  • std::set y std::map: estructuras ordenadas para almacenar elementos únicos y pares clave-valor.
  • Iteradores: herramientas para recorrer contenedores de forma flexible y eficiente.
  • Algoritmos STL: como sort, find, count, entre otros, para manipular contenedores.
  • Funciones lambda: funciones anónimas útiles para aplicar lógica directamente dentro de los algoritmos.

Vayamos a la parte prácica del capítulo.

TEjercicio 1: Ordenar una lista de números y eliminar duplicados
Enunciado:
Escribe un programa que reciba una lista de enteros, elimine los duplicados y los ordene de menor a mayor utilizando la STL.

Código:

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>

int main() {
std::vector<int> numeros = {5, 3, 8, 3, 9, 1, 5, 3, 8};

std::set<int> sin_duplicados(numeros.begin(), numeros.end()); // elimina duplicados
std::vector<int> resultado(sin_duplicados.begin(), sin_duplicados.end());

std::sort(resultado.begin(), resultado.end());

std::cout << "Números ordenados sin duplicados: ";
for (int n : resultado) {
std::cout << n << " ";
}
std::cout << std::endl;

return 0;
}

Explicación:

  • Se usa un std::set para eliminar duplicados automáticamente (los set no permiten valores repetidos).
  • Luego, se convierte de nuevo a vector para poder aplicar std::sort.
  • Finalmente, se imprime la lista ordenada.
Ejercicio 2: Contar ocurrencias de palabras en un texto
Enunciado:
Escribe un programa que cuente cuántas veces aparece cada palabra en un vector de strings. Usa std::map.

Código:

#include <iostream>
#include <map>
#include <vector>
#include <string>

int main() {
std::vector<std::string> palabras = {"casa", "sol", "casa", "luna", "sol", "casa"};
std::map<std::string, int> conteo;

for (const std::string& palabra : palabras) {
conteo[palabra]++;
}

std::cout << "Frecuencia de palabras:\n";
for (const auto& par : conteo) {
std::cout << par.first << ": " << par.second << "\n";
}

return 0;
}

Explicación:

Luego se imprimen todas las palabras y sus frecuencias.

Se usa un std::map para asociar cada palabra con un contador.

Cada vez que una palabra aparece, se incrementa su valor en el mapa.

Ejercicio 3: Filtrar valores pares usando lambda y std::copy_if
Enunciado:
Usa una función lambda con std::copy_if para filtrar los números pares de un std::vector y guardarlos en otro vector.

Código:

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
std::vector<int> numeros = {1, 2, 3, 4, 5, 6, 7, 8};
std::vector<int> pares;

std::copy_if(numeros.begin(), numeros.end(), std::back_inserter(pares),
[](int n) { return n % 2 == 0; });

std::cout << "Números pares: ";
for (int n : pares) {
std::cout << n << " ";
}
std::cout << std::endl;

return 0;
}

Explicación:

El resultado son solo los números pares.

Se usa std::copy_if con una lambda que devuelve true si el número es par.

std::back_inserter permite insertar elementos al final del vector de salida (pares).

Logo C++

Bibliografía del tutorial de C/C++.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *