Contenedores desordenados en C++: unordered_map y unordered_set

Los contenedores unordered_map y unordered_set forman parte de la biblioteca estándar de C++ desde el estándar C++11. A diferencia de map y set, que utilizan árboles rojinegros y mantienen un orden estricto, estos nuevos contenedores emplean tablas hash como estructura subyacente, permitiendo operaciones promedio en tiempo constante O(1) para inserción, búsqueda y eliminación.

Características generales

  • No garantizan ningún orden específico de los elementos.
  • El rendimiento depende de la calidad de la función hash y del factor de carga (relación entre número de elementos y número de cubos).
  • Son ideales cuando se requiere acceso rápido por clave o valor, sin necesidad de recorridos ordenadso.

std::unordered_map

Almacena pares clave-valor únicos, donde cada clave sirve como identificador único para acceder a su valor asociado.

Construcción

std::unordered_map<int, std::string> m1; // vacío
std::unordered_map<int, std::string> m2 = {{10, "diez"}, {20, "veinte"}};
auto m3 = m2; // copia
std::unordered_map<int, std::string> m4(std::move(m3)); // movimiento

Acceso a elementos

El operador [] permite acceso directo, pero inserta un par con valor por defecto si la clave no existe:

std::unordered_map<int, std::string> um;
um[5] = "cinco";       // inserta {5, "cinco"}
std::string s = um[6]; // inserta {6, ""} y devuelve cadena vacía

Búsqueda y modificación

if (um.find(5) != um.end()) {
    // clave encontrada
}
um.erase(5); // elimina por clave
um.insert({7, "siete"}); // evita inserción duplicada

Operaciones de cubo

size_t total_buckets = um.bucket_count();
size_t bucket_idx = um.bucket(5);
size_t elementos_en_bucket = um.bucket_size(bucket_idx);

std::unordered_set

Almacena valores únicos sin orden, optimizados para verificación rápida de pertenenica.

Construcción y consulta

std::unordered_set<int> us = {1, 2, 3, 4};
if (us.count(3)) {
    // el valor 3 está presente
}

Inserción y eliminación

auto result = us.insert(5);
if (result.second) {
    // inserción exitosa
}
us.erase(2); // elimina el valor 2

Estrategia de hashing

Permite controlar el comportamiento interno de la tabla hash:

float factor = us.load_factor();        // elementos / cubos
us.max_load_factor(0.75f);             // ajusta umbral máximo
us.reserve(100);                       // preasigna espacio para ~100 elementos
us.rehash(50);                         // fuerza al menos 50 cubos

Ejemplo completo

#include <iostream>
#include <unordered_set>
#include <unordered_map>

int main() {
    std::unordered_map<std::string, int> frecuencias;
    frecuencias["manzana"] = 5;
    frecuencias["pera"] = 3;

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

    std::unordered_set<std::string> palabras = {"rojo", "verde", "azul"};
    if (palabras.find("verde") != palabras.end()) {
        std::cout << "Color encontrado.\n";
    }

    return 0;
}

Etiquetas: C++ STL unordered_map unordered_set tabla hash

Publicado el 8-20 04:40