2012-05-14 6 views
6

Sono confuso che è più efficiente?STL MAP dovrebbe utilizzare find() o [n] identificatore per trovare l'elemento nella mappa?

Come possiamo accedere direttamente alla mappa, perché dobbiamo utilizzare find?

Ho solo bisogno di sapere in che modo è più efficiente.

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

grazie in anticipo! :)

risposta

18

Utilizzando find significa che non lo fanno involontariamente creare un nuovo elemento nella mappa se la chiave non esiste, e - cosa più importante - questo significa che è possibile utilizzare find per cercare un elemento se tutto quello che hai è un riferimento costante alla mappa.

Ciò significa che è necessario verificare il valore restituito di find. In genere si va in questo modo:

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 Questo è assolutamente importante quando non si desidera creare l'elemento se non è stato trovato. –

2

Come possiamo accedere direttamente carta, perché abbiamo bisogno di usare trovare?

Perché map<>::operator[] è talvolta pericoloso. Se un elemento non esiste, allora:

  • si inserisce
  • valore inizializzarlo
  • rendimenti di riferimento di valore

Così restituisce sempre un riferimento valido di valore, anche se una la chiave non esiste in precedenza. Questo comportamento non è inteso molte volte.

D'altra parte map<>::find() è più sicuro; perché restituisce end(), se un valore non esce. Un altro vantaggio di find() è che restituisce un iteratore che contiene riferimenti a chiave (first) e valore (second) entrambi.

+0

'operator []' restituisce il riferimento al valore, non alla chiave. – jpalecek

+0

@jpalecek, si è scambiato. Thx – iammilind

+0

* 'map <> :: find()' è più sicuro *. Beh, in realtà no.L'esempio più semplice è il codice nella domanda, in cui l'utente non sta verificando se l'iteratore è valido. In quel caso particolare 'map <> :: operator []' è * più sicuro * in quanto garantisce che il programma non abbia un comportamento indefinito. –

1

L'operatore [] nella mappa non è costante è logaritmico. La maggior parte dei libri sottolinea questo fatto e sottolinea che è un po 'fuorviante. Quindi sia find che [] operator hanno la stessa complessità.

Si noti che l'operatore [] creerà la voce anche se non esiste mentre find restituirà end() in tal caso.

0

Questo codice e documento viene prelevata dal 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. 

Si noti come l'ultimo accesso (all'elemento 'd') inserisce un nuovo elemento della mappa con quella chiave e inizializzato al valore predefinito (a vuoto string) anche se è accessibile solo per recuperarne il valore. La mappa delle funzioni membro :: trova non produce questo effetto.