¿Cómo eliminar un par específico de un mapa múltiple de C ++?

3 minutos de lectura

Avatar de usuario de Jim Blackler
jim blackler

#include <map>

...

multimap<char,int> mymap;

mymap.insert(pair<char,int>('a',10));
mymap.insert(pair<char,int>('b',15));
mymap.insert(pair<char,int>('b',20));
mymap.insert(pair<char,int>('c',25));

Digamos que ahora quiero eliminar uno de los pares que acabo de agregar al mapa.

Tengo ejemplos para eliminar una entrada de clave completa, que para la tecla ‘b’ eliminaría tanto ‘b’,15 como ‘b’,20.

Pero, ¿cuál es el código para eliminar solo, digamos, el par ‘b’,20?

Avatar de usuario de Charles Salvia
Carlos Salvia

Puedes usar std::multimap<char, int>::equal_range, que le dará un rango de iteradores que contiene todos los pares que tienen una determinada clave. Entonces, si busca ‘b’, obtendrá un rango de iterador que contiene todos los pares que tienen ‘b’ como clave.

Luego puede simplemente iterar sobre el rango y borrar cualquier par que considere adecuado, borrando el iterador.

multimap<char,int> mymap;

mymap.insert(pair<char,int>('a',10));
mymap.insert(pair<char,int>('b',15));
mymap.insert(pair<char,int>('b',20));
mymap.insert(pair<char,int>('c',25));

typedef multimap<char, int>::iterator iterator;
std::pair<iterator, iterator> iterpair = mymap.equal_range('b');

// Erase (b,15) pair
//
iterator it = iterpair.first;
for (; it != iterpair.second; ++it) {
    if (it->second == 15) { 
        mymap.erase(it);
        break;
    }
}

  • ¡Gracias por esto! También tenga en cuenta que puede haber más de un par que tenga la clave Y el valor correspondiente (por ejemplo, más de un par (‘b’,15)), por lo que es posible que no desee romper después de encontrar solo el primer resultado. También tenga en cuenta que con multimap, aparentemente la función erase() no invalida otros iteradores (excepto el iterador borrado), por lo que puede seguir iterando (o al menos eso es lo que deduzco de esta página: cplusplus.com/reference/map/multimap/erase)

    – Jamin Grey

    18 mayo 2013 a las 19:27


  • Puede seguir iterando, sí, pero el iterador borrado real se invalida, por lo que primero debe recuperar un iterador para el siguiente elemento.

    – Carlos Salvia

    21 de mayo de 2013 a las 17:07

  • ¿No resultará esto tener una complejidad lineal si todas las claves son iguales? Por ejemplo, digamos que insertamos los siguientes pares: (‘k’, 1), (‘k’, 2), (‘k’, 3), (‘k’, 4) Ahora, si quiero eliminar el par (‘k’, 4), recorreré todos los pares hasta que encuentre (‘k’, 4).

    – Gautham

    6 mayo 2018 a las 14:34


  • @Gautham Buscaría si boost bimap o multiindex pueden hacerlo de manera eficiente, creo que sí. Iba a intentar crear un ejemplo, pero ahora no tengo la paciencia para luchar contra los documentos de Boost.

    – Ciro Santilli OurBigBook.com

    08/01/2020 a las 17:40

En caso de que necesite continuar iterando después de la primera coincidencia, primero debe recuperar un iterador para el siguiente elemento, ya que el iterador borrado se invalida.

Una forma de lograr esto, a partir de C++ 11, es usar el valor de retorno de la función de borrado, que es un iterador del elemento que sigue al último elemento eliminado (o multimap::end, si se eliminó el último elemento) . Tenga cuidado con la versión basada en claves que devuelve el número de elementos borrados, no un iterador.

Sobre la base de la valiosa respuesta de Charles Salvia, que muestra cómo borrar el par (b,15), obtienes

multimap<char,int> mymap;

mymap.insert(pair<char,int>('a',10));
mymap.insert(pair<char,int>('b',15));
mymap.insert(pair<char,int>('b',20));
mymap.insert(pair<char,int>('c',25));

typedef multimap<char, int>::iterator iterator;
std::pair<iterator, iterator> iterpair = mymap.equal_range('b');

// Erase (b,15) pair
//
iterator it = iterpair.first;
for (; it != iterpair.second; ) {
    if (it->second == 15) { 
        it=mymap.erase(it);
    }
    else
        ++it;
}

¿Ha sido útil esta solución?