2010-10-07 18 views
7

GegebenWie Schlüsselwerte in std :: map Container

std::map<int,std::string> myMap; 
fillMyMapWithStuff(myMap); 

// modify key values - I need to add a constant value to each key 
for (std::map<int,std::string>::iterator mi=myMap.begin(); mi != myMap.end(); ++mi) 
{ 
    // ... 
} 

ändern Was ist ein guter Weg, um etwas Neuindexierung anwenden? Muss ich den alten Eintrag entfernen und einen neuen mit dem neuen Schlüssel und dem alten Wert hinzufügen?

Antwort

8

Sieht so aus, als ob Sie besser daran sind, eine neue Karte zu erstellen und sie danach zu tauschen. Sie haben nur n einfügen Operationen anstelle von n Löschungen und n Insertionen.

+0

+1, in diesem Fall, wenn die gesamte Karte neu aufgebaut wird, ist es besser als sogar löschen + einfügen mit Hinweis. – Cubbi

+0

Um fair zu sein, seine n einfügen Operationen + 1 Swap-Operation. – Justicle

+0

@Justin: Aber ein Tausch sollte eine sinnlose Zeit dauern. –

3

Ja, Sie müssen. Der Schlüssel ist const, solange er sich in der Karte befindet.

5

Ja, Sie müssen den alten Eintrag entfernen und einen neuen mit dem neuen Schlüssel hinzufügen. Schlüssel sind nicht änderbar.

Wenn Sie nur ein oder wenige Elemente modifizieren, können Sie dies effizient tun, indem Sie map::insert mit der Position des neuen Elements andeuten. Da Ihre neuen Schlüssel sich sicher irgendwo befinden nach die alten Schlüssel, können Sie mit dem Iterator, der auf das alte Element verweist, einen Hinweis geben. Allerdings müssen Sie darauf achten, die neu eingefügten Schlüssel nicht neu zu bewerten (indem Sie beispielsweise von vorne nach hinten iterieren). Wenn Sie die gesamte Karte ändern, ist es effizienter, einfach einen neuen zu erstellen.

2

Ich denke, Sie müssen eine neue Karte erstellen. Wenn Sie innerhalb der Schleife neue Schlüssel löschen und hinzufügen, kann dies die Integrität des Iterierens über die alten Schlüssel zerstören und die gerade eingefügten Schlüssel nicht berühren. (Es sei denn, Sie wissen, wie Ihre Schlüssel verteilt sind und setzen Sie Ihre eigene Logik dort.)

std::map<int,std::string> myMap; 
fillMyMapWithStuff(myMap); 

std::map<int,std::string> newMap; 

// modify key values - I need to add a constant value to each key 
for (std::map<int,std::string>::iterator mi=myMap.begin(); mi != myMap.end(); ++mi) 
{ 
    newMap[mi->first] = mi->second; 
} 
2

Es gibt eine weitere Option. Wenn diese Operation ein wichtiges Merkmal Ihrer Sammlung ist und die Leistung wichtig ist, können Sie vermeiden, die Karte vollständig zu kopieren. Sie können eine Klasse erstellen, die operator[] sowie andere Zugriffsmethoden und Mutatoren überlädt, und die aktuelle Verschiebung des Schlüsselwerts hinzufügen.