Zugriff auf map-Wert von index
Wenn ich eine Struktur haben, wie
std::map<string, int> myMap;
myMap["banana"] = 1;
myMap["apple"] = 1;
myMap["orange"] = 1;
Wie kann ich auf myMap[0]?
Ich weiß, dass die Karte Arten intern und ich bin mit diesem feinen, ich möchte einen Wert in der map-index. Ich habe versucht myMap[0], aber ich bekomme die Fehlermeldung:
Error 1 error C2679: binary '[' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
Ich begreife, dass ich tun könnte etwas wie diese:
string getKeyAtIndex (int index){
map<string, int>::const_iterator end = myMap.end();
int counter = 0;
for (map<string, int>::const_iterator it = myMap.begin(); it != end; ++it) {
counter++;
if (counter == index)
return it->first;
}
}
Aber sicher ist dies äußerst ineffizient? Gibt es einen besseren Weg?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre
map
soll nicht zugegriffen werden, die Art und Weise, ist es indiziert, die durch Tasten nicht durch Positionen. Einmap
iterator bidirektionale, genau wie einlist
, also die Funktion, die Sie verwenden, ist nicht ineffizienter als der Zugriff auf einelist
nach position. Ihre Funktion geschrieben werden kann, mit Hilfe vonstd::advance( iter, index )
abbegin()
. Wenn Sie möchten, random access durch die position dann mit einemvector
oder einedeque
.Vorherigen Antwort (siehe Kommentar): Wie wäre es einfach
myMap.begin();
Könnten Sie implementieren eine random-access-Karte mithilfe eines Vektor-backing-store, die ist im wesentlichen ein Vektor von Paaren. Sie natürlich verlieren alle Vorteile der standard-Bibliothek Karte an diesem Punkt.
Gibt es vielleicht eine Umsetzung von spezifischen (nicht-portable) - Methode, um Ihr Ziel zu erreichen, aber nicht eine, die tragbar ist.
Im Allgemeinen, die
std::map
ist implementiert als eine Art binärer Baum, in der Regel sortiert nach dem key. Die definition des ersten Elements unterscheidet sich je nach Bestellung. Auch in Ihrer definition, ist element[0] den Knoten an der Spitze des Baumes oder der linke Blattknoten?Viele binäre Bäume implementiert werden, die als verknüpfte Listen. Die meisten verlinkten Listen können nicht direkt aufgerufen werden wie ein array, da element 5, Sie haben zu Folgen Sie den links. Dies ist per definition.
Können Sie dieses Problem beheben, indem Sie sowohl eine
std::vector
und einstd::map
:std::map
.std::vector
an die gewünschte positionan.
Den
std::map
es erlauben, eine effiziente Methode für den Zugriff auf das Objekt durch die-Taste.Die
std::vector
es erlauben, eine effiziente Methode für den Zugriff auf den Objekt-index.Speichern von Zeigern erlaubt nur eine Instanz des Objekts, anstatt zur Pflege mehrerer Kopien.
Gut, eigentlich kann man es nicht. Die Art und Weise, die Sie gefunden haben, ist sehr unefficient, Sie haben eine rechnerische Komplexität von O(n) (n Operationen worst-case, wobei n die Anzahl der Elemente in einer Karte).
Zugriff auf ein Element in einem Vektor oder in einem array haben Komplexität O(1) durch Vergleich (Konstante Komplexität, die eine einzelne operation).
Bedenkt, dass Karte ist intern umgesetzt, als rot-schwarz-Baum (oder avl-Baum, es hängt von der Implementierung) und jeder insert -, delete-und lookup-operation sind O(log n) worst case (es erfordert Logarithmus zur Basis 2 Operationen zum finden eines Elements in der Baumstruktur), das ist ziemlich gut.
Einer Weise, die Sie behandeln können, ist die Verwendung einer benutzerdefinierten Klasse, die haben innen sowohl eine Vektor-und eine Karte.
Einfügen am Ende der Klasse werden durchschnittlich O(1), Suche nach Namen werden in O(log n), - Suche nach index O(1) aber in diesem Fall, entfernen operation O(n).
können Sie eine andere Karte wie Behältern .
halten Sie eine Größe der Felder machen kann binary search tree einfach zu random access .
hier ist meine Umsetzung ...
std-Stil , random-access-iterator ...
Größe ausgeglichenen Baum ...
https://github.com/mm304321141/zzz_lib/blob/master/sbtree.h
und B+ - Baum ...
https://github.com/mm304321141/zzz_lib/blob/master/bpptree.h