std::list.erase in Schleife einfacher möglich?
-
Geht das erase auch einfacher?
std::list<int> list; list.push_back(2); list.push_back(4); list.push_back(8); list.push_back(2); list.push_back(4); list.push_back(8); list.push_back(2); list.push_back(7); list.push_back(1); int a=0; int b=0; std::list<int>::iterator i = list.begin(); std::list<int>::iterator end = list.end(); while(i!=end) { if(*i==2) { a++; std::list<int>::iterator del = i; ++i; list.erase(del); } else if(*i==4) { b++; std::list<int>::iterator del = i; ++i; list.erase(del); } else { ++i; } }
-
Ich bin mir nicht sicher, ob es mit list auch geht, aber bei vector mache ich es immer so:
list.erase(list.begin()+4); list.erase(list.begin()+2);
-
i ist doch nicht der index
-
Oh, habe ich nicht richtig gesehen. Dann halt so:
for(i=0;i<list.size();i++) { if (2 == list[i] || 4 == list[i]) list.erase(list.begin()+i--); }
-
Unregistriert schrieb:
Oh, habe ich nicht richtig gesehen. Dann halt so:
for(i=0;i<list.size();i++) { if (2 == list[i] || 4 == list[i]) list.erase(list.begin()+i--); }
list hat keinen random access
Was man vll noch machen kann ist postinkrement verwenden und die Temporäre kopie tatsächlich temporär machen:
while(i!=end) { if(*i==2) { a++; list.erase(i++); } else if(*i==4) { b++; list.erase(i++); } else { ++i; } }
-
i=list.erase(i);
??
-
std::list schrieb:
Geht das erase auch einfacher?
int count = li.size(); li.remove(2); count -= li.size();
aber nur mit std::list!
-
Hi,
es gibt noch std::remove_if() und list::remove_if()
Damit kann man auch kompliziertere Bedingungen an das Listenelement formulieren als bloße "Gleichheit" und Ersters klappt auch mit anderen Containern...dabei muss man aber bedenken, dass die unerwünschten Elemente nur "ans Ende sortiert" werden und man dann die entsprechende Range noch (ggf. containerspez.) gelöscht werden müssen.bool single_digit (const int& value) { return (value<10); } void machs_weg(list<int>& L) { L.erase(remove_if(L.begin(), L.end(), single_digit), L.end()); }
Gruß,
Simon2.
-
Shade Of Mine schrieb:
i=list.erase(i);
??
Ups, hab irgendwie gedacht, dass erase auch nix zurück gibt, wie remove.
@queer_boy & Simon2: Ich will aber auch noch was anderes machen als löschen.
-
in der schleife allgemein? oder nur mit dem element, das du rauslöscht?
wenn du etwas genauer bist, kann dir vielleicht auch jemand eine elegante lösung mit den standardalgorithmen anbieten.
-
Ne, das von Shade Of Mine passt schon. Das war nur ein Beispiel, eigentlich passiert viel mehr.
-
std::list schrieb:
...@queer_boy & Simon2: Ich will aber auch noch was anderes machen als löschen.
Würde ich aber lassen. Wenn ich richtig sehe, erliegst Du der "premature optimization"-Versuchung: Du willst
a) wissen, wie viele Elemente mit einer bestimmten Eigenschaft es gibt (bzw. für jedes Element mit dieser Eigenschaft "irgendetwas machen") und
b) dann dieses Element aus der Liste entfernen.
und (vermutlich) weil Du Dir einen Performancegewinn erhoffst, willst Du die beiden Aufgaben im selben Schleifendruchlauf abarbeiten. ... Es ist aber nicht das erase(), sondern genau dieser "verfrühte Optimierungsansatz", der zu dem häßlichen Code führt, den Du (zu Recht) beklagst.Warum nicht einfach erst Deine gewünschte Aktion (find(), for_each(), count(), ....) und danach das remove() ? Wäre IMHO auf jeden Fall sauberer ....
Gruß,
Simon2.