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?
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;
}