unordered_map, unordered_set en lugar de hash escrito a mano

unordered_map requiere archivos de cabecera #include <unordered_map>
unordered_set requiere archivos de cabecera #include <unordered_set>
Ambos se implementan basan en valores hash y están fuera de servicio , por lo que la complejidad del tiempo de adición , eliminación, modificación y comprobación es O (1), la cual es más rápido que map and set, se implementan en base a un árbol binario balanceado (árbol rojo-negro), mantienen dinámicamente una secuencia ordenada , y la complejidad de tiempo es O (logn).

Para saber cómo escribir una tabla hash a mano, consulte: aprendizaje preliminar de tablas hash, hashes de cadenas

Introducción a unordered_map

unordered_map<key,value> m;
Defina un tipo de mapa, la clave es la clave principal y el valor es el valor. La asignación de la clave principal al valor se puede realizar . Es una actualización de una matriz bidimensional. En una matriz bidimensional, la clave primaria solo puede ser de tipo int. El subíndice comienza desde 0, y el mapa es correcto. La clave primaria puede ser de cualquier tipo.

El marco básico es el siguiente:

#include <iostream>
#include <unordered_map>
using namespace std;
typedef pair<string,int> PSI;
int main(){
    
    
    unordered_map<string,int> hash;
    
    return 0;
}

Operaciones comunes

hash.size()    Devuelve el tamaño del contenedor del mapa actual (número de elementos)
hash.empty()    determina si el contenedor está vacío map, devuelve un retorno vacío, no vacío 0
hash.clear()    Borrar todos los elementos del mapa
hash.erase(key)  eliminar elementos clave
hash.erase(it)   eliminando el iterador de elemento puntiagudo, se puede usar junto con el función de búsqueda

1. Insertar elemento
hash["lyh"]=20;

Durante el proceso de inserción, primero elimine el hash [clave] y luego vuelva a asignarlo.
Si solo escribe hash[key], si la clave existe, solo existe el proceso de recuperación; si la clave no existe, es el proceso de inserción, y se inserta 0 por defecto.

hash.insert(PSI("lyh",40));
equivalente a:PSI t={"efg",456}; hash.insert(t);

Comprenda el uso de la estructura binaria de pares, también puede asignar valores por separado,t.first="efg"; t.second=456;

Se pueden insertar ① y ②, pero ① se puede actualizar. Dado que solo puede haber una clave principal en el mapa, no se puede repetir . Cuando la clave ya existe en el mapa, el método ① se puede utilizar para actualizar, pero el método ② no se insertará.

2. Elementos de acceso
① Acceso único a través de la clave principal
cout<<hash["lyh"];
② A través del iterador, se puede lograr todo acceso transversal o único

for (auto it=hash.begin();it!=hash.end();it++) 
        cout<<it->first<<" "<<it->second<<endl;

Auto está escrito en C ++, que puede determinar automáticamente el tipo de variable. De hecho, debería ser
unordered_map<string,int>::iterator it;

Preste atención al acceso del método ①, que hash[key]es una operación de búsqueda para devolver el valor del valor de la clave actual. Si la clave no existe en el hash, se insertará por defecto, y el valor inicial es 0. Por lo tanto, en el caso de no estar seguro de si la clave existe, es mejor determinar si la clave existe a través de la función de buscar o contar para evitar insertarla accidentalmente en el hash.

3. Juicio Clave primariaExiste
hash.find(key); Encuentra si la clave especificada existe, hay un iterador que apunta a la clave , de lo contrario, devuelve un iterador que apunta a hash.end ()

hash.count(key);Devuelve el número de elementos correspondientes a la clave. Dado que la clave del contenedor del mapa no puede repetirse, el valor devuelto solo puede ser 0 o 1 , que también sirve para determinar si existe el elemento clave-valor.

Introducción a unordered_set

unordered_set<int> hash;

La asignación en el mapa mencionado anteriormente es clave-> valor. Tanto la clave como el valor pueden ser de cualquier tipo, pero la clave principal no se puede repetir;
y el conjunto es más como una matriz, que solo puede ser una asignación de int-> valor , es decir, la clave primaria es solo. Puede ser un tipo int, similar a un contenedor de vectores, pero no se permite repetir el valor de un conjunto . Además, no admite la indexación basada en la clave principal int, y solo se puede recorrer a través de iteradores, es decir, set solo puede almacenar valores de valor .

El marco básico es el siguiente:

#include <iostream>
#include <unordered_set>

using namespace std;

int main()
{
    
    
    unordered_set<int> hash;

    return 0;
}

Operaciones comunes

hash.size();Obtener el número de elementos
hash.empty();Determinar si está vacío
hash.clear();Borrar el conjunto
hash.erase(x);Eliminar el elemento con el valor x
hash.erase(it);Eliminar el elemento apuntado por el iterador
hash.erase(first,last);Eliminar los elementos entre [primero, último) señalados por el iterador

1. Insertar función de
hash.insert(x);inserción de elemento Insertar elemento x en la colección

2. El
vector de elemento de acceso admite el acceso de subíndice y el mapa admite el acceso de clave primaria. Pero solo se puede acceder al conjunto uno por uno según los iteradores.

for (auto it=hash.begin();it!=hash.end();it++)
        cout<<(*it)<<endl;

De la misma manera, auto significaunordered_set<int>::iterator it;

3. Determinar si el elemento existe. El
mapa no puede determinar si el valor existe. Es para determinar si la clave principal existe y la clave principal no se puede repetir; en el conjunto, debido a que se determina la clave principal, el conjunto determina si el valor del valor existe.

hash.find(x);Devuelve un iterador, apuntando al elemento x, si no existe, hash.end();
hash.count(x);apúntalo.Determina si el elemento x existe en el conjunto, y el valor de retorno es 1 o 0.

Las operaciones más utilizadas en la tabla hash son insertar y recuperar, juzgar si existe un número, y la eliminación rara vez se usa. Puede elegir la simulación de conjunto o mapa de manera apropiada.

La diferencia entre mapa y conjunto es:

El mapa almacena un par de valores <tipo 1, tipo 2> (<clave, valor>) y el conjunto almacena un valor.
Específicamente, existe una gran diferencia entre la función de búsqueda y la función de recuento. El mapa es encontrar la clave principal y el conjunto es encontrar el valor.

Descripción del Título

Sobre la base de la descripción del título de la palabra azul , introduzca cómo utilizar unordered_map y unordered_set en su lugar.

Breve descripción del título:
Mantenga una colección y respalde las siguientes operaciones:

"I x", inserte un número x;
"Q x", pregunte si el número x ha aparecido en el conjunto;

Ahora necesitamos realizar N operaciones y generar el resultado correspondiente para cada operación de consulta.

rango de datos

1≤N≤10 5
−10 9 ≤x≤10 9

análisis:

¿Qué tipo de set deberíamos llevar? Los datos de entrada x rango para llevar al alcance de 2e9, los datos de -1e9 a 1e9, pero en realidad ingresaron solo 1e5 meses si, como una fila de barril que abrió una enorme matriz para almacenar, obviamente un desperdicio, por lo que una discretización de La idea es mapear los datos de entrada de [-1e9,1e9] a los datos de [1,1e5], por lo que se usa el hash. Anteriormente, era un hash escrito a mano y ahora usa el contenedor stl, pero el hash escrito a mano tiene una mayor ventaja y velocidad más rápida.

Utilice unordered_set para simular

El conjunto solo puede almacenar el valor del valor y solo se puede buscar de acuerdo con el valor del valor, por lo que cada x debe insertarse como el valor del valor. Afortunadamente, la pregunta es si ha aparecido x, no el número de veces que aparece x, porque el set container No se pueden almacenar elementos duplicados.

#include <iostream>
#include <unordered_set>

using namespace std;

int main()
{
    
    
    unordered_set<int> hash;
    int num,x;
    char op[2];
    cin>>num;
    while (num--) {
    
    
        cin>>op>>x;
        if (op[0]=='I') hash.insert(x);
        else hash.count(x)?puts("Yes"):puts("No");
    }
    return 0;
}

Utilice unordered_map para simular

unordered_map <clave, valor>, unordered_map inserta una estructura binaria <clave, valor> , que se asigna de clave a valor y solo se puede encontrar por clave, no por valor. Por lo tanto, la x ingresada cada vez se utiliza como clave de clave primaria, y el valor mantiene el número de apariciones de la clave de clave primaria. Dado que la pregunta no requiere el número de veces, es suficiente almacenar el signo 1 que tiene apareció.

#include <iostream>
#include <unordered_map>

using namespace std;

int main()
{
    
    
    unordered_map <int,int> hash;
    int num,x;
    char op[2];
    cin>>num;
    while (num--) {
    
    
        cin>>op>>x;
        if (op[0]=='I') hash[x]=1;  //根据key在那里标记是否插入过
        else hash.count(x)?puts("Yes"):puts("No");
    }        "hash.find(x)找到的是迭代器,找不到即指向hash.end()"
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/HangHug_L/article/details/114135343
Recomendado
Clasificación