std::map insert
-
Hallo,
ich kopiere Elemente in eine std::map via Insert().
Der neue Eintrag in der Map wird jedoch Alphabetisch sortiert.
Wie kann ich das verhindern ? Es soll at end angehangen werden.Beispiel:
std::map<std::string, std::string> params; params.insert(std::map<std::string, std::string>::value_type("Baum","grün")); params.insert(std::map<std::string, std::string>::value_type("Auto","rot"));
Ergebnis: //alphabetisch sortiert
(0) Auto rot
(1) Baum grünErwünscht: //unsortiert wie eingegeben
(0) Baum grün
(1) Auto rotAusgelesen wird das so:
for (std::map<std::string, std::string>::const_iterator i = r->m_params.begin(); i != r->m_params.end(); i++) { CString ¶m(i->first.c_str() + CString("=") + i->second.c_str()); }
Mir ist klar das der erste Eintrag von zwei als index gild , aber
die Speicherfolge kann doch gleich der eingabe folge sein.Danke für Hinweise
Karsten
-
Wenn du das unbedingt brauchst, nimm einen std::vector<std::pair<std::string, std::string>>.
-
Hallo,
ich kann leider keinen Vector verwenden da andere diese map
weiter verarbeiten.Muss ich also eine zweite Liste zur indizierung parallel verwenden,
das ist sehr unschön. ich kann dem feld auch keinen dritten Eintrag zuweisen.
-
Wieso brauchst du denn eine Ordnung?
Und was heißt "a andere diese map weiter verarbeiten."?
Wieso gehen denn dann zwei Listen*?*Ich hoffe du meinst jetzt nicht std::list. std::list ist für 90+% der Anwendungsfälle ungeeignet...
-
Es ist ein Webserver, der umfangreich
mit diesem Array arbeitet. Ich kann nicht die ganze verarbeitung
verändern, am Ende brauche ich eine historisch indizierte Liste,
bekomme aber eine alphabetisch sortierte, der Voreintrag bestimmt
später die Sortiergruppe der Einträge. Die "anderen" sind andere
Programmteile.
-
Und wieso geht dann der std::vector nicht?
-
weil er nicht zwei teile nebeneinander ablegt:
i->first.c_str()
i->second.c_str()
Ich muss mich den anderen Aufgaben unterordnen , diese verwenden nun mal
map, da kann man nicht einfach alle konzepte verwerfen, ich denke
eher es gäbe eine Option um das Alphabetische sortieren im Vorfeld
zu unterdrücken und gut ist.Wenn dem nicht so ist, muss ich eine indizierliste parallel erzeugen
was man nicht möchte.
-
struct Comp { bool operator()(const std::string& lhs, const std::string& rhs) const { // implement your comparison logic here } };
Instances of this class is callable (hence "functor") with two string parameters, and should return true or false based in a strict weak ordering logic.
Then instantiate the map using the functor type:
std::map<string, list<pair<string, int>>, Comp> List;
Now the map will use your comparison logic internally to define the ordering of its elements.
Fummelig, ein Sortflag wäre ja nicht schlecht gewesen....
-
std::map
erfordert eine konsistente Sortierung. Wenn du nach Zeit sortieren willst, musst du ein entsprechendes Attribut als Key einfügen.std::string
-Keys in einer Map chronologisch zu ordnen ist nicht möglich.Aber wie gesagt,
std::map
ist der falsche Container. Wer sowas vorschreibt, hat keine Ahnung, oder du hast ein paar Details in der Aufgabenstellung vergessen. Wieso genau musst dustd::map
verwenden?P.S. Nächstes Mal kannst du gleich sagen, wenn du noch auf StackOverflow nachfragst.
-
Ich habe nicht gefragt, sondern die Suche intensiviert.
Und ich verstehe die Unterschiede, es ging um die
Option der chronologischen beeinflußung im Vorfeld.
ich bau das nun um, nach std::vectorDanke für deine Hilfe.
Gruß K.
-
Es ist schon irgendwie möglich mit
std::map
, z.B. indem man einen Index mitführt wie in der StackOverflow-Antwort.Aber es ist wahnsinnig ineffizient und umständlich, wenn es nur darum geht, die Einfügereihenfolge beizubehalten. Du verlierst all die Vorteile von
std::vector
(schnelle Speicherbeschaffung, keine Speicherfragmentierung und dadurch weniger Cache-Misses, wenig Speicherverbrauch, Random Access). Einen produktiven Einsatz würde ich also nicht empfehlen, zumal du noch immer keine eigentlichen Gründe dafür genannt hast.Wenn du unbedingt bei der Index-Lösung bleiben willst:
map<string, list<pair<string, int>>>
wie auf StackOverflow vorgeschlagen ist merkwürdig, warum den Index im Value und nicht Key speichern? Key ist ja das, wonach sortiert wird. Und warum kommt überhaupt der Vorschlag, den Index in den String einzubauen? Mehr Sinn würde also
map<pair<size_t, string>, string>
machen. Wenn der Index als erstes Element im
std::pair
gespeichert wird, wird automatisch danach sortiert wird und du musst gar keinen Funktor schreiben. Wenn du Mehrfacheinträge brauchst, nimmstd::multimap
. Zudem brauchtstd::list
sehr gute Argumente um eingesetzt zu werden. Für Indizes solltest du für Indizesstd::size_t
und nichtint
nehmen.Edit: Ah, hab vorher was überlesen. Wenn das so umständlich sein muss, vergiss den letzten Absatz.
Dass du zusätzlich auf StackOverflow nachfragst ist kein Problem, aber es wäre nett das zu erwähnen
-
Möglicherweise ist
boost::bimap
eine Option?