2009-12-21 2 views

Antwort

467

Verwenden map::find

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

Wenn Sie nur prüfen möchten, ob ein bestimmter Schlüssel existiert, verwenden Sie wahrscheinlich lieber ['map :: count'] (http://www.cplusplus.com/reference/map/map/count/) – tomsmeding

+5

@tomsmeding Es gibt nur einen einzigen Schlüssel in einer std :: map. Also zählt entweder 0 oder 1. Ist einer effizienter als der andere? – goelakash

+24

@goelakash kaum; es ist nur so, dass "count" ein "int" zurückgibt, während "find" einen ganzen Iterator zurückgibt. Sie speichern die Konstruktion des Iterators :) Wenn Sie nachher * den Wert * verwenden wollen, wenn er existiert, verwenden Sie find und speichern Sie das Ergebnis. – tomsmeding

26

können Sie .find() verwenden:

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

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

Ich glaube, Sie map::find wollen. Wenn m.find("f") gleich m.end() ist, wurde der Schlüssel nicht gefunden. Andernfalls gibt find einen Iterator zurück, der auf das gefundene Element zeigt.

Der Fehler liegt daran, p.first ist ein Iterator, der nicht für Stream-Insertion funktioniert. Ändern Sie Ihre letzte Zeile in cout << (p.first)->first;. ist ein Paar von Iteratoren, p.first ist ein Iterator, p.first->first ist die Schlüsselzeichenfolge.

Eine Karte kann immer nur ein Element für einen bestimmten Schlüssel haben, daher ist equal_range nicht sehr nützlich. Es ist für Map definiert, da es für alle assoziativen Container definiert ist, aber es ist viel interessanter für Multimap.

+0

Eigentlich, weil es ein Paar Iteratoren zu einer Karte ist, sollte es "cout << p.first-> first;" – stefaanv

+0

Ich habe meine Antwort repariert, danke. Das ist, was ich bekomme, um meinen Code nicht zu kompilieren. Und Sie haben Recht (in einem gelöschten Kommentar) über die Gültigkeitsprüfung, aber ich habe nur versucht zu erklären, warum er nicht p.first drucken konnte, und es ist nicht, weil es ungültig ist - wir wissen, dass "f" gefunden wird. Da ich die Verwendung von equal_range überhaupt nicht empfehle, zeige ich hier keinen Code zur Fehlerüberprüfung. –

+0

Wow, Sie scannen wirklich SO. Ich habe es nur der Vollständigkeit halber hinzugefügt, weil dein Punkt klar war. Ich habe die Gültigkeitsprüfung zu meiner vorherigen Antwort hinzugefügt, aber deine Antwort hat mich geschlagen, also habe ich sie gelöscht, weil sie sowieso nicht so viel hinzugefügt hat, wie du erwähnt hast. – stefaanv

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

Wenn Sie andere API verwenden möchten, finden dann gehen für 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"; 
2

Seien Sie vorsichtig in die mit dem Ende führen finden Vergleich wie für Karte 'm' als alle Antwort haben getan über map :: iterator i = m.find ("f");

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

Sie sollten nicht versuchen, und sämtliche Aufgaben wie das Drucken der Schlüssel oder Wert mit Iterator i Wenn es gleich m.end() sonst wird es zu Segmentierungsfehler führen.

219

Um zu überprüfen, ob ein bestimmter Schlüssel in der Karte vorhanden ist, die Funktion count Mitglied verwenden in eine der folgenden Möglichkeiten:

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

Die documentation für map::find sagt: „Ein anderes Mitglied Funktion, map::count, kann verwendet werden, um zu überprüfen, ob ein bestimmter Schlüssel existiert. "

Die documentation für map::count sagt: "Da alle Elemente in einem Kartencontainer eindeutig sind, kann die Funktion nur 1 zurückgeben (wenn das Element gefunden wird) oder Null (andernfalls)."

Um einen Wert aus der Karte über einen Schlüssel abrufen, die Sie existieren nicht kennen, verwenden map::at:

value = m.at(key) 

Im Gegensatz zu map::operator[], map::at wird einen neuen Schlüssel in der Karte nicht erstellen, wenn der angegebene Schlüssel existiert nicht .

+21

Wenn Sie beide Operationen ausführen, überprüfen Sie, ob es existiert und dann etwas dagegen tun. Verwenden Sie stattdessen 'find'.Das Attribut 'second' des Iterators, das von' find' zurückgegeben wird, kann verwendet werden, um den Wert des Schlüssels abzurufen. Wenn Sie 'count', dann' at' oder 'operator []' verwenden, führen Sie zwei Operationen durch, wenn Sie nur eine verwendet haben könnten. – OdraEncoded

+4

Dies sollte die ausgewählte Antwort sein. – modulitos

+1

Sie müssen nicht> 0, == 1 oder! = 0; das ist die genaue Prüfung, die C++ in einer if-Anweisung durchführt (Bedingung! = 0), also können Sie einfach 'if (m.count (key))' – jv110

2
map<string, string> m; 

Prüfschlüssel vorhanden ist oder nicht, und die Rückzahl auftritt (0/1 in der Karte):

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

Prüfschlüssel vorhanden ist oder nicht, und das Rück Iterator:

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

in Ihrer Frage, der Fehler durch schlechte operator<< Überlastung verursacht, weil p.first ist map<string, string>, Sie können es nicht ausdrucken. versuchen Sie dies:

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

Sie haben einen Tippfehler. Ändern Sie "cout" zu "count" – Rivka

+1

Und dieser Tippfehler kann wirklich jemanden abschleudern, da der 'cout' etwas ganz anderes bedeuten kann als' count' – modulitos

0

den Code std :: map Vergleich :: finden und std :: map :: Graf, ich die erste würde sagen kann einige Leistungsvorteil ergeben:

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); 
    } 
-2

Wenn Sie ein Kartenpaar vergleichen möchten, können Sie diese Methode verwenden:

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

Dies ist eine nützliche Technik.

+0

Als Anfänger mit C++ - Programmierung bin ich wirklich neugierig, warum diese Antwort abgelehnt wird. Warum ist diese Antwort unpopulär? – gromit190

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

Natürlich, wenn Sie Ihnen ausgefallenere konnten immer Vorlage aus einer Funktion, die auch nahm eine gefundene Funktion und eine nicht gefunden Funktion, um so etwas bekommen wollten:

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

Und verwenden Sie es wie folgt aus :

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

der Nachteil ist, mit einem guten Namen kommen, „find_and_execute“ ist umständlich, und ich kann nicht mit etwas besser aus der Spitze von meinem Kopf kommen ...

-1
map <int , char>::iterator itr; 
    for(itr = MyMap.begin() ; itr!= MyMap.end() ; itr++) 
    { 
     if (itr->second == 'c') 
     { 
      cout<<itr->first<<endl; 
     } 
    } 
+2

Bitte erläutern Sie Ihren Code. Ein Ausschnitt ohne Erklärung ist auf lange Sicht nicht hilfreich. – iBug

Verwandte Themen