c++ - Come trovare se esiste una determinata chiave in una std :: map C ++


Sto provando a controllare se una determinata chiave è in una mappa e in qualche modo non posso farlo:

typedef map<string,string>::iterator mi;
map<string, string> m;
m.insert(make_pair("f","++--"));
pair<mi,mi> p = m.equal_range("f");//I'm not sure if equal_range does what I want
cout << p.first;//I'm getting error here

quindi, come posso stampare ciò che è in p?



Answers



Usa map::find

if ( m.find("f") == m.end() ) {
  // not found
} else {
  // found
}



Per verificare se esiste una determinata chiave nella mappa, utilizzare la funzione membro di count in uno dei seguenti modi:

m.count(key) > 0
m.count(key) == 1
m.count(key) != 0

La documentazione per map::find dice: "Un'altra funzione membro, map::count , può essere usata per controllare solo se esiste una determinata chiave."

La documentazione per map::count dice: "Poiché tutti gli elementi in un contenitore di mappe sono univoci, la funzione può restituire solo 1 (se l'elemento è trovato) o zero (altrimenti)."

Per recuperare un valore dalla mappa tramite una chiave che tu sai di esistere, usa map :: at :

value = m.at(key)

A differenza di map :: operator [] , map::at non creerà una nuova chiave nella mappa se la chiave specificata non esiste.




Puoi usare .find() :

map<string,string>::iterator i = m.find("f");

if (i == m.end()) { /* Not found */ }
else { /* Found, i->first is f, i->second is ++-- */ }



m.find == m.end() // not found 

Se si desidera utilizzare altre API, quindi cercare m.count(c)>0

 if (m.count("f")>0)
      cout << " is an element of m.\n";
    else 
      cout << " is not an element of m.\n";



Penso che vuoi la map::find . Se m.find("f") è uguale a m.end() , la chiave non è stata trovata. Altrimenti, find restituisce un iteratore che punta all'elemento trovato.

L'errore è dovuto p.first fatto che p.first è un iteratore, che non funziona per l'inserimento del flusso. Cambia l'ultima linea in cout << (p.first)->first; . p è una coppia di iteratori, p.first è un iteratore, p.first->first è la stringa di chiavi.

Una mappa può avere sempre un solo elemento per una determinata chiave, quindi equal_range non è molto utile. È definito per la mappa, perché è definito per tutti i contenitori associativi, ma è molto più interessante per la multimap.




Fai attenzione nel confrontare il risultato di ricerca con la fine come per la mappa 'm' come tutte le risposte hanno fatto sopra la mappa :: iterator i = m.find ("f");

 if (i == m.end())
 {
 }
 else
 {
 }  

non dovresti provare ad eseguire alcuna operazione come stampare la chiave o il valore con iterator i se è uguale a m.end () altrimenti causerà un errore di segmentazione.




map<string, string> m;

la chiave di controllo esiste o no, e restituisce il numero di occorrenze (0/1 nella mappa):

int num = m.count("f");  
if (num>0) {    
    //found   
} else {  
    // not found  
}

la chiave di controllo esiste o no e restituisce l'iteratore:

map<string,string>::iterator mi = m.find("f");  
if(mi != m.end()) {  
    //found  
    //do something to mi.  
} else {  
    // not found  
}  

nella tua domanda, l'errore causato da un operator<< brutto operator<< sovraccarico, perché p.first è map<string, string> , non puoi stamparlo. prova questo:

if(p.first != p.second) {
    cout << p.first->first << " " << p.first->second << endl;
}



template <typename T, typename Key>
bool key_exists(const T& container, const Key& key)
{
    return (container.find(key) != std::end(container));
}

Ovviamente, se volessi diventare più esperto, potresti sempre definire una funzione che ha anche una funzione trovata e una funzione non trovata, qualcosa del genere:

template <typename T, typename Key, typename FoundFunction, typename NotFoundFunction>
void find_and_execute(const T& container, const Key& key, FoundFunction found_function, NotFoundFunction not_found_function)
{
    auto& it = container.find(key);
    if (it != std::end(container))
    {
        found_function(key, it->second);
    }
    else
    {
        not_found_function(key);
    }
}

E usalo in questo modo:

    std::map<int, int> some_map;
    find_and_execute(some_map, 1,
        [](int key, int value){ std::cout << "key " << key << " found, value: " << value << std::endl; },
        [](int key){ std::cout << "key " << key << " not found" << std::endl; });

Il rovescio della medaglia di questo è un buon nome, "find_and_execute" è imbarazzante e non riesco a trovare niente di meglio in cima alla mia testa ...




Confrontando il codice di std :: map :: find e std :: map :: count, direi che il primo potrebbe dare qualche vantaggio in termini di prestazioni:

const_iterator find(const key_type& _Keyval) const
    {   // find an element in nonmutable sequence that matches _Keyval
    const_iterator _Where = lower_bound(_Keyval); // Here one looks only for lower bound
    return (_Where == end()
        || _DEBUG_LT_PRED(this->_Getcomp(),
            _Keyval, this->_Key(_Where._Mynode()))
                ? end() : _Where);
    }

size_type count(const key_type& _Keyval) const
    {   // count all elements that match _Keyval
    _Paircc _Ans = equal_range(_Keyval); // Here both lower and upper bounds are to be found, which is presumably slower.
    size_type _Num = 0;
    _Distance(_Ans.first, _Ans.second, _Num);
    return (_Num);
    }



Se vuoi confrontare la coppia di mappe puoi usare questo metodo:

typedef map<double, double> TestMap;
TestMap testMap;
pair<map<double,double>::iterator,bool> controlMapValues;

controlMapValues= testMap.insert(std::pair<double,double>(x,y));
if (controlMapValues.second == false )
{
    TestMap::iterator it;
    it = testMap.find(x);

    if (it->second == y)
    {
        cout<<"Given value is already exist in Map"<<endl;
    }
}

Questa è una tecnica utile.