Ich versuche zu überprüfen, ob sich ein bestimmter Schlüssel in einer Karte befindet und kann es etwas nicht:
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
Wie kann ich also drucken, was in p steht?
c++
dictionary
stl
Wir können nichts tun
quelle
quelle
std::pair<iterator,bool> insert( const value_type& value );
Was ist der Bool, den es zurückgibt? sagt es, ob der Schlüssel bereits vorhanden ist oder nicht?Antworten:
Verwenden
map::find
quelle
map::count
count
eineint
Weilefind
einen ganzen Iterator zurückgibt. Sie speichern die Konstruktion des Iterators :) Wenn Sie den Wert anschließend verwenden möchten, falls vorhanden, verwenden Sie natürlich find und speichern Sie das Ergebnis.count
undfind
in der Geschwindigkeit nahezu identisch sind, wenn Karten verwendet werden, für die eindeutige Schlüssel erforderlich sind. (1) Wenn Sie die Elemente nicht benötigen, um eine bestimmte Reihenfolge aufrechtzuerhalten, verwenden Sie std :: unordered_map , das nahezu konstante Suchvorgänge aufweist und beim Speichern von mehr als einigen Paaren sehr nützlich sein kann. (2) Wenn Sie den Wert verwenden möchten, falls vorhanden, speichern Sie das Ergebnis von :: find und verwenden Sie den Iterator, um zweiauto it = m.find("f"); if (it != m.end()) {/*Use it->second*/}
Verwenden Sie die
count
Elementfunktion auf eine der folgenden Arten , um zu überprüfen, ob ein bestimmter Schlüssel in der Karte vorhanden ist :In der Dokumentation zu
map::find
heißt es: "Eine andere Mitgliedsfunktionmap::count
kann verwendet werden, um nur zu überprüfen, ob ein bestimmter Schlüssel vorhanden ist."In der Dokumentation zu
map::count
heißt es: "Da alle Elemente in einem Kartencontainer eindeutig sind, kann die Funktion nur 1 (wenn das Element gefunden wird) oder Null (andernfalls) zurückgeben."Um einen Wert aus der Karte über einen Schlüssel abrufen , dass Sie wissen , existieren, die Verwendung der Karte :: at :
Im Gegensatz Karte :: operator [] ,
map::at
wird nicht einen neuen Schlüssel in der Karte erstellen , wenn der angegebene Schlüssel existiert nicht.quelle
find
stattdessen. Dassecond
Attribut des von zurückgegebenen Iteratorsfind
kann verwendet werden, um den Wert des Schlüssels abzurufen. Wenn Siecount
dann verwendenat
oderoperator[]
zwei Operationen ausführen, bei denen Sie nur eine hätten verwenden können.if(m.count(key))
int
bis stößtbool
. Obwohl es andere C ++ - Compiler gibt, die keine ähnliche Warnung ausgeben, bevorzuge ich die Verwendung eines expliziten Vergleichs , um die Absicht klar zu machen und die Lesbarkeit zu verbessern. Beachten Sie, dass andere Sprachen wie C # eine solche implizite Konvertierung verbieten , um die Möglichkeit subtiler Programmierfehler zu vermeiden.C ++ 20 gibt uns
std::map::contains
die Möglichkeit dazu.quelle
Sie können verwenden
.find()
:quelle
Wenn Sie eine andere API verwenden möchten, suchen Sie go for
m.count(c)>0
quelle
Ich denke du willst
map::find
. Wennm.find("f")
gleich ist,m.end()
wurde der Schlüssel nicht gefunden. Andernfalls gibt find einen Iterator zurück, der auf das gefundene Element zeigt.Der Fehler liegt daran, dass
p.first
es sich um einen Iterator handelt, der beim Einfügen von Streams nicht funktioniert. Ändern Sie Ihre letzte Zeile incout << (p.first)->first;
.p
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,
equal_range
ist also nicht sehr nützlich. Es ist für die Karte definiert, da es für alle assoziativen Container definiert ist, für Multimap jedoch viel interessanter.quelle
C++17
vereinfachte dies etwas mehr mit einemIf statement with initializer
. Auf diese Weise können Sie Ihren Kuchen haben und ihn auch essen.quelle
Prüfschlüssel vorhanden oder nicht, und Rückgabewert von tritt auf (0/1 in der Karte):
Überprüfen Sie, ob der Schlüssel vorhanden ist oder nicht, und geben Sie den Iterator zurück:
in Ihrer Frage, verursacht der Fehler durch schlechte
operator<<
Überlastung, dap.first
istmap<string, string>
, können Sie es nicht drucken aus. Versuche dies:quelle
cout
count
Wenn Sie schicker werden möchten, können Sie natürlich jederzeit eine Funktion vorlegen, die auch eine gefundene Funktion und eine nicht gefundene Funktion enthält.
Und benutze es so:
Der Nachteil dabei ist, dass ein guter Name "find_and_execute" unangenehm ist und ich mir nichts Besseres einfallen lassen kann ...
quelle
Seien Sie vorsichtig beim Vergleichen des Suchergebnisses mit dem Ende wie für map 'm', da alle Antworten über map :: iterator i = m.find ("f") erfolgen.
Sie sollten nicht versuchen, eine Operation wie das Drucken des Schlüssels oder Werts mit dem Iterator i auszuführen, wenn dieser gleich m.end () ist. Andernfalls führt dies zu einem Segmentierungsfehler.
quelle
Wenn man den Code von std :: map :: find und std :: map :: count vergleicht, würde ich sagen, dass der erste einen Leistungsvorteil bringen kann:
quelle
Ich weiß, dass diese Frage bereits einige gute Antworten hat, aber ich denke, meine Lösung ist es wert, geteilt zu werden.
Es funktioniert für beide
std::map
undstd::vector<std::pair<T, U>>
ist in C ++ 11 verfügbar.quelle
Wenn Sie ein Kartenpaar vergleichen möchten, können Sie folgende Methode verwenden:
Dies ist eine nützliche Technik.
quelle
quelle