vector: erase + Einfügen in Schleife?
-
Eisflamme schrieb:
Edit:
Ich könnte vor dem Durchlauf den vector auf das doppelte seiner aktuellen Größe reservern, da ich nach dem Durchlauf nie mehr als N*2 Elemente enthalten habe. Würde das garantieren, dass push_back kein Resizing macht und Iteratoren daher erhalten bleiben?Wenn die capacity des vectors groß genug für die Einfügeaktion ist, ist dir garantiert, dass push_back die Iteratoren gültig lässt.
Eisflamme schrieb:
Edit:
Puh, wenn es keine triviale Lösung gibt, werd ich wohl einfach einen Zweitvector nutzen, da alle neuen Elemente einfügen und die vectors später zusammenfügen. Die neu erstellten Elemente erfordern nämlich eigentlich gar keine Iteration mehr... elegant lässt sich Obiges nicht lösen? Vielleicht ist vector auch der falsche Container?Wie immer die Frage: Was soll es werden?
-
Es geht um einen Stringparser. Der String enthält kommaseparierte Ausdrücke, die unabhängig voneinander sind. Deswegen splitte ich den String erst nach ',' und füge alle Elemente in einen vector ein und validiere dann jedes einzelne Element.
Ungültige Elemente werden gelöscht, manche sind aber auch einfach nur ungünstig/unkonventionell geschrieben, diese werden geändert. Und manchmal schreibt man etwas abgekürzt, dann werden aus einem Element eben zwei Elemente. Später wird der vector wieder in einen kommaseparierten String umgewandelt.
-
Also wenn ich das richtig sehe, machst du folgendes:
- String zerpflücken und nach vector kopieren.
- vector validieren und geänderte Dinge wieder in vector stopfen.
- vector-Teile in String kopieren.
Warum so umständlich? Den vector (oder die vectoren) brauchst du dabei doch garnicht:
- Nimm dir nacheinander jeden der kommaseparierten Substrings
- Jage ihn durch deinen Validator/Parser
- Schmeiße das oder die Ergebnisse direkt in den Ergebnis-String, jeweils gefolgt von einem Komma
Keine zwischendurch-Vectoren nötig.
Oder hast du wichtige Details ausgelassen?
-
Gibt es einen tieferen Grund, warum du
1. die abgeänderten Tokens auch noch indem vector zwischenspeicherst, anstatt sie direkt in die Zieldatenstruktur einzufügen? Ein Grund dafür könnten Abhängigkeiten zwischen den Tokens sein, die einen Zugriff auf bereits verarbeitete Tokens nötig machen oder die Notwendigkeit, später immer noch Zugriff auf die Tokens zu haben. Deine Beschreibung klingt aber tendenziell eher so, als wäre beides nicht der Fall.
2. die Tokens in dem Vector zwischenspeicherst, anstatt sie direkt zu ändern und in die Zieldatenstruktur einzufügen? Mögliche Gründe wären wie oben.edit: Da war pumuckl mit der gleichen Idee schneller.
-
Hm, stimmt, das könnte ich umstellen. Ich fand's halt spontan angenehmer mit einem vector zu arbeiten. Es kann auch sein, dass die Überprüfung ergibt, dass nichts geändert werden muss. Dann würde ich quasi umsonst alles von String1 nach String2 schieben. Aber der Aufwand ist wohl vernachlässigbar, wenn die Überprüfung sowieso stattfindet.

Edit: Oh, jetzt fällt mir doch noch ein, wieso das gut ist. Ich will die Teile später noch sortieren...
-
Eisflamme schrieb:
ohne dass ich mir den Wert merke und nach dem push_back suche?
Ich verstehe die Frage nicht. Nach push_back steht das neue Element an letzter Stelle. Wofür suchen?
-
Wenn der iterator nicht mehr gültig ist, muss ich ihn reproduzieren und wenn ich nicht am Anfang anfangen will, muss ich den eben über eine Suche finden.
-
Wie wäre es mit Indizes, wenn du einen vector hast?
-
Eisflamme schrieb:
Wenn der iterator nicht mehr gültig ist, muss ich ihn reproduzieren und wenn ich nicht am Anfang anfangen will, muss ich den eben über eine Suche finden.
Was heißt reproduzieren? Nicht am Anfang anfangen, sondern suchen? Du redest in Rätseln. Ich seh selbst für den Fall, dass du nächträglich Iteratoren für alle neu eingefügten Elemente haben willst, keinen Bedarf für Suchen, weil die Elemente alle ab einer bestimmten Stelle hintereinander im Container stehen.
-
Michael:
Wenn ich push_back mache ist mein aktueller iterator ungültig. Ich iteriere durch die ganze Schleife aber via iterator. Also muss ich, damit ich an derselben Stelle weiterlaufen kann wie vorher, ja irgendwie an besagte Stelle kommen.SeppJ:
Ja, das ginge. Hatte ganz übersehen, dass ich ja swap-erasen kann. Ohne das wäre es umständlich geworden das Element an der entsprechenden Indexstelle zu löschen.
-
Wenn ich dich recht verstanden habe, möchtest du den Behälter doch bloß zum sortieren. Warum dann kein (multi-)set? Und das Iterieren sparst du dir ganz, so wie ich und pumuckl es weiter oben schon vorgeschlagen haben. Also Pseudocode:
while(getline(quelle, zeile, ',')) verarbeite_zeile_und_füge_ergebnis_dem_set_hinzu(zeile, das_set); for(alle set_elemente) schreibe_raus(ziel, set_element);