¿Cómo verificar si std :: map contiene una clave sin insertar?


Respuestas:


305

Uso my_map.count( key ); solo puede devolver 0 o 1, que es esencialmente el resultado booleano que desea.

Alternativamente my_map.find( key ) != my_map.end()funciona también.


40
@John: Eso apesta a optimización prematura. En GCC (y estoy seguro de que los sistemas más razonables), map::countse implementa como find(__x) == end() ? 0 : 1;. Para multimapel puede tener un argumento de rendimiento, pero esa no es la pregunta de OP y todavía prefiero la elegancia.
Potatoswatter

42
No, el argumento de optimización prematura solo es válido si la optimización requiere un esfuerzo que en este caso no es necesario.
markh44

13
No es verdad. No es prematuro si hace que el código sea más fácil de leer o elimina la sobrecarga innecesaria. En este caso, si count () se implementa a través de find () de todos modos, entonces llamar a find () elimina directamente una función call ... ergo, es una optimización madura . Creo que usar la llamada find () también es más obvio, pero esa es una preferencia puramente personal.
Tim Keating

9
No es una optimización prematura conocer el rendimiento de las funciones de la biblioteca antes de acostumbrarse a usarlas. En este caso, tiene razón, no importa, pero tampoco la minúscula diferencia estilística entre encontrar y contar. Creo que lleva demasiado lejos la retórica de la "optimización prematura". Debe tomar cualquier hábito de optimización "gratuito" que pueda encontrar y utilizarlo para el desarrollo diario. Es cuando los codificadores sucumben a la trampa de pagar costos en legibilidad / tiempo de desarrollo / etc., todo por "ganancias de rendimiento" no medidas que la retórica de optimización prematura se convierte en el consejo correcto para dar.
VoidStar

10
Lejos, std solo debería agregar una maldita has(k)/ contains(k)como cualquier otra clase de mapa sensata en el planeta. Mal diseño de la interfaz. El enfoque find () es demasiado detallado y count(k)definitivamente no está en paridad semántica has(k). Para el caso tampoco lo es find(k). Mira el recuento de visitas en esta pregunta.
Jarrod Smith

46

La respuesta de Potatoswatter está bien, pero prefiero usar findo en su lower_boundlugar. lower_boundes especialmente útil porque el iterador devuelto puede usarse posteriormente para una inserción insinuada, si desea insertar algo con la misma clave.

map<K, V>::iterator iter(my_map.lower_bound(key));
if (iter == my_map.end() || key < iter->first) {    // not found
    // ...
    my_map.insert(iter, make_pair(key, value));     // hinted insertion
} else {
    // ... use iter->second here
}

Esto es sutilmente diferente de cómo dice que lo está haciendo ... la única diferencia es que valuese puede omitir el cálculo si la inserción es innecesaria.
Potatoswatter

1
Claro, entiendo que al OP no le importa insertar, por lo que una lower_boundsolución basada en es exagerada. Acabo de mencionar mi respuesta "para completar"; como dije, el tuyo es perfectamente adecuado. :-)
Chris Jester-Young

44
Sí, esta es una buena respuesta y no estoy en desacuerdo con nada. Simplemente señalando la relación con la alternativa inserta priori. En realidad, hay otra diferencia si se usa a multimap, el lower_boundmétodo se inserta al comienzo del rango equivalente, mientras que el insertmétodo simple se agrega al final del rango.
Potatoswatter

2
No es la respuesta a la pregunta, pero mi pregunta pobre me lleva a la respuesta correcta aquí ... Necesito hacer la inserción / actualización. : D
Hunter-Orionnoir

1
@ Hunter ¿Puedes mostrarme tu código? Si no es masivo, probablemente pueda revisarlo por usted.
Chris Jester-Young

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.