2012-05-14 13 views
6

Estoy confundido, ¿cuál es más eficiente?STL MAP debería usar el identificador find() o [n] para encontrar el elemento en el mapa?

Como podemos acceder al mapa directamente, ¿por qué tenemos que usar find?

Solo necesito saber qué camino es más eficiente.

#include <iostream> 
#include <map> 
using namespace std; 

int main() 
{ 
    map<char,int> mymap; 
    map<char,int>::iterator it; 

    mymap['a']=50; 
    mymap['b']=100; 
    mymap['c']=150; 
    mymap['d']=200; 

    //one way 

    it=mymap.find('b'); 
    cout << (*it).second <<endl; 

    //another way 
     cout << mymap['b'] <<endl; 

    return 0; 
} 

gracias de antemano! :)

Respuesta

18

Usando find significa que no lo hace sin darse cuenta crear un nuevo elemento en el mapa si no existe la clave, y - más importante - esto significa que se puede utilizar find a buscar una elemento si todo lo que tiene es constante referencia al mapa.

Eso, por supuesto, significa que debe verificar el valor de retorno de find. Normalmente es la siguiente:

void somewhere(const std::map<K, T> & mymap, K const & key) 
{ 
    auto it = mymap.find(key); 
    if (it == mymap.end()) { /* not found! */ } 
    else     { do_something_with(it->second); } 
} 
+2

+1 Esto es absolutamente importante cuando no desea crear el elemento si no se encuentra. –

2

Como podemos acceder directamente a un mapa, ¿por qué tenemos que utilizar encontrar?

Porque map<>::operator[] es a veces desagradable. Si un elemento no existe, entonces:

  • lo inserta
  • valor inicialícela
  • referencia los rendimientos del valor

Por lo tanto, siempre devuelve una referencia válida de valor, incluso si una la clave no existía previamente. Este comportamiento no está destinado muchas veces.

Por otro lado, map<>::find() es más seguro; porque devuelve end(), si un valor no sale. Otra ventaja de find() es que devuelve un iterador que contiene referencias a la clave (first) y al valor (second).

+0

'operator []' devuelve la referencia al valor, no a la tecla. – jpalecek

+0

@jpalecek, sí, se canjeó. Thx – iammilind

+0

* 'map <> :: find()' es más seguro *. Bueno, en realidad no.El ejemplo más simple es el código en la pregunta, donde el usuario no verifica si el iterador es válido. En ese caso particular, 'map <> :: operator []' es * safe *, ya que garantiza que el programa no tiene un comportamiento indefinido. –

1

El operador [] en el mapa no es constante, es logarítmico. La mayoría de los libros hacen hincapié en este hecho y señalan que es un poco engañoso. Entonces ambos find y [] operator tienen la misma complejidad.

Tenga en cuenta que el operador [] creará la entrada incluso si no existe mientras find devolverá end() en ese caso.

0

Este código y doc es tomado de cplusplus.com

// accessing mapped values 
#include <iostream> 
#include <map> 
#include <string> 
using namespace std; 

int main() 
{ 
    map<char,string> mymap; 

    mymap['a']="an element"; 
    mymap['b']="another element"; 
    mymap['c']=mymap['b']; 

    cout << "mymap['a'] is " << mymap['a'] << endl; 
    cout << "mymap['b'] is " << mymap['b'] << endl; 
    cout << "mymap['c'] is " << mymap['c'] << endl; 
    cout << "mymap['d'] is " << mymap['d'] << endl; 

    cout << "mymap now contains " << (int) mymap.size() << " elements." << endl; 

    return 0; 
} 

OP: 
mymap['a'] is an element 
mymap['b'] is another element 
mymap['c'] is another element 
mymap['d'] is 
mymap now contains 4 elements. 

Aviso cómo el último acceso (al elemento 'd') inserta un nuevo elemento en el mapa con esa clave y se inicializa a su valor por defecto (un vacío cadena) aunque se acceda solo para recuperar su valor. El mapa de funciones miembro :: find no produce este efecto.

Cuestiones relacionadas