Contenedores STL y expresiones lambda en C++11

std::vector

std::vector es un arreglo dinámico que puede crecer o reducirse en tiempo de ejecución. Se define en la cabecera <vector>.

Creación e inicialización

#include <iostream>
#include <vector>

int main() {
    // Vector vacío
    std::vector<int> v1;

    // Con tamaño fijo (inicializados a 0)
    std::vector<int> v2(5);

    // Con tamaño y valor por defecto
    std::vector<int> v3(5, 10);

    // Con lista de inicialización
    std::vector<int> v4 = {1, 2, 3, 4, 5};
    return 0;
}

Insertar y eliminar elementos

int main() {
    std::vector<int> nums = {10, 20, 30};
    nums.push_back(40);                 // {10,20,30,40}
    nums.insert(nums.begin() + 1, 15);  // {10,15,20,30,40}
    nums.pop_back();                    // {10,15,20,30}
    nums.erase(nums.begin() + 2);       // {10,15,30}
    return 0;
}

Nota: insert y erase tienen complejidad O(n) porque desplazan elementos.

Acceso a elementos

int main() {
    std::vector<int> datos = {5, 10, 15};
    std::cout << datos[0] << '\n';          // 5
    std::cout << datos.at(1) << '\n';       // 10
    for (auto it = datos.begin(); it != datos.end(); ++it)
        std::cout << *it << ' ';
    return 0;
}

Métodos útiles

  • resize(n): cambia el tamaño; si es mayor agrega elementos por defecto.
  • capacity(): capacidad actual de almacenamiento.
  • clear(): elimina todos los elementos (la capacidad no cambia).
  • empty(): retorna si está vacío.
  • size(): cantidad de elementos.
int main() {
    std::vector<int> v = {1,2,3};
    std::cout << v.size() << '\n';       // 3
    std::cout << v.capacity() << '\n';   // posiblemente 3 o más
    v.resize(5);
    std::cout << v.size() << '\n';       // 5
    v.clear();
    std::cout << v.empty() << '\n';      // true
    return 0;
}

std::list

std::list es una lista doblemente enlazada. Ideal para inserciones y eliminaciones frecuentes en cualquier posición. Cabecera <list>.

Creación

#include <list>

int main() {
    std::list<int> lst;                    // vacía
    std::list<int> lst2(5, 10);            // {10,10,10,10,10}
    std::list<int> lst3 = {1,2,3,4,5};     // por inicialización
    return 0;
}

Insertar y eliminar

int main() {
    std::list<int> nums = {1,2,3};
    nums.push_back(4);          // {1,2,3,4}
    nums.push_front(0);         // {0,1,2,3,4}
    nums.pop_back();            // {0,1,2,3}
    nums.pop_front();           // {1,2,3}
    nums.remove(2);             // {1,3}
    return 0;
}

Acceso (no aleatorio)

int main() {
    std::list<int> nums = {10,20,30};
    // Solo front() y back()
    std::cout << nums.front() << ' ' << nums.back() << '\n'; // 10 30

    // Iteradores
    for (auto it = nums.begin(); it != nums.end(); ++it)
        std::cout << *it << ' ';

    // Recorrido inverso
    for (auto it = nums.rbegin(); it != nums.rend(); ++it)
        std::cout << *it << ' ';

    // For basado en rango
    for (auto x : nums) std::cout << x << ' ';
    return 0;
}

Métodos adicionales

  • sort(): ordena la lista.
  • reverse(): envierte el orden.
  • unique(): elimina elementos consecutivos duplicados.
  • merge(): fusiona dos listas ordenadas.
int main() {
    std::list<int> lst = {3,1,4,1,5};
    lst.sort();                // {1,1,3,4,5}
    lst.unique();              // {1,3,4,5}
    lst.reverse();             // {5,4,3,1}
    return 0;
}

std::queue

Cola FIFO (First-In First-Out). Cabecera <queue>. Permite añadir por el final y eliminar por el frente.

#include <queue>

int main() {
    std::queue<int> cola;
    cola.push(10);
    cola.push(20);
    cola.push(30);

    std::cout << cola.front() << '\n'; // 10
    cola.pop();                           // elimina 10
    std::cout << cola.front() << '\n'; // 20
    std::cout << cola.size() << '\n';  // 2
    while (!cola.empty()) cola.pop();     // vaciado
    return 0;
}

Además de push, pop, front, back, empty y size.


std::priority_queue

Cola con prioridad basada en montículo (heap). Por defecto es un max‑heap. Cabecera <queue>.

#include <queue>

int main() {
    std::priority_queue<int> pq; // max‑heap
    pq.push(30);
    pq.push(10);
    pq.push(40);
    std::cout << pq.top() << '\n'; // 40
    pq.pop();                       // elimina 40
    std::cout << pq.top() << '\n'; // 30
    return 0;
}

Personalizar la prioridad

// Min‑heap
std::priority_queue<int, std::vector<int>, std::greater<int>> pq_min;

// Con struct y operador <
struct Punto {
    int x, y;
    bool operator<(const Punto& otro) const {
        return x > otro.x; // menor x tiene mayor prioridad
    }
};
std::priority_queue<Punto> pq_puntos;

std::map y std::multimap

std::map es un contenedor asociativo que almacena pares clave‑valor ordenados por clave (implementado como árbol rojo‑negro). Cada clave es única. Cabecera <map>.

Operaciones básicas

#include <map>
#include <string>

int main() {
    std::map<int, std::string> capitulos;
    capitulos.insert({1, "Introducción"});
    capitulos[2] = "Desarrollo";
    capitulos[3] = "Conclusión";

    // Acceso
    std::cout << capitulos[2] << '\n';       // Desarrollo
    std::cout << capitulos.at(1) << '\n';   // Introducción

    // Búsqueda
    auto it = capitulos.find(2);
    if (it != capitulos.end())
        std::cout << "Encontrado: " << it->second << '\n';

    // Eliminación
    capitulos.erase(2);

    // Recorrido
    for (const auto& par : capitulos)
        std::cout << par.first << ": " << par.second << '\n';

    return 0;
}

Comparador personalizado

struct Descendente {
    bool operator()(int a, int b) const { return a > b; }
};
std::map<int, std::string, Descendente> mapa_desc; // claves descendentes

std::multimap permite claves repetidas, pero no tiene operador [].

#include <map>

int main() {
    std::multimap<int, std::string> mm;
    mm.insert({1, "uno"});
    mm.insert({1, "one"});
    mm.insert({2, "dos"});

    auto it = mm.find(1);
    mm.erase(it); // elimina solo la primera ocurrencia

    std::cout << mm.count(1) << '\n'; // 1
    return 0;
}

std::set

Conjunto de elementos únicos y ordenados. Cabecera <set>.

#include <set>

int main() {
    std::set<int> numeros;
    numeros.insert(3);
    numeros.insert(1);
    numeros.insert(4);
    numeros.insert(1); // ignorado

    std::cout << numeros.size() << '\n'; // 3

    auto it = numeros.find(3);
    if (it != numeros.end()) std::cout << *it << " encontrado\n";

    numeros.erase(4);
    for (int x : numeros) std::cout << x << ' '; // 1 3
    return 0;
}

Al igual que map, se puede personalizar el criterio de ordenación con un funtor.


Expresiones lambda

Una lambda es una función anónima definida en línea. Sintaxis básica:

[captura](parámetros) -> tipo_retorno { cuerpo }

Ejemplos

#include <algorithm>
#include <vector>

int main() {
    // Lambda simple
    auto saludo = []() { std::cout << "Hola mundo\n"; };
    saludo();

    // Con parámetros
    auto suma = [](int a, int b) { return a + b; };
    std::cout << suma(5, 3) << '\n';

    // Captura por valor y referencia
    int x = 10;
    auto por_valor = [x]() { return x * 2; };       // captura copia
    auto por_ref = [&x]() { x += 5; };               // captura referencia

    // Con std::sort
    std::vector<int> v = {4, 2, 7, 1};
    std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; }); // descendente
    for (int n : v) std::cout << n << ' '; // 7 4 2 1

    return 0;
}

Las lambdas son especialmente útiles para algoritmos de la STL y callbacks.

Etiquetas: C++11 std::vector std::list std::queue std::priority_queue

Publicado el 6-17 16:32