std::remove. Löscht nicht alle Elemente?
-
Hallo,
ich habe folgenden Code.
using namespace std; int main() { vector<int> vec; vector<int> bvec;[code] for(int i = 1; i<=20; ++i) { vec.push_back(i); if(i%2 == 0) bvec.push_back(i); } for(vector<int>::iterator iter = bvec.begin(); iter != bvec.end(); ++iter) { remove(vec.begin(), vec.end(), *iter); } for(vector<int>::iterator iter = vec.begin(); iter != vec.end(); ++iter) { cout << *iter << endl; } }Die erste Schleife soll beide Vektoren füllen. Den ersten mit Zahlen [1; 20] und den zweiten nur mit geraden Zahlen. Die zweite Schleife löscht alle Zahlen aus bvec in vec. Die dritte gibt das ganze aus. Leider sieht die Ausgabe so aus:
(Anzahl der '20' stimmt nicht. Es werden insgesamt genau 20 Zahlen ausgegeben.)1
3
5
7
9
11
13
15
17
19
20
20
20
20
[...]Jetzt wundere ich mich über die Ausgabe sehr. Müssten die 20iger nicht komplett fehlen? Und warum ist die Vectorgrößte immernoch 20? (mit size() abgefragt)
Nutze ich remove etwa völlig falsch?Panke
Edit:
Aaaaah - da hab ich mich im Forum verlaufen. Kann mich einer nach C++ verschieben?
-
hab öfters mal die Erfahrung mit der STL gemacht, dass beim Löschen von Elementen großer Mist passiert.
Die Lösung war dann ein Element löschen, neu initialisieren. nicht schön aber es ging.
std::remove gibt auch einen iterator zurück, der auf das Ende der verbleibenden Elemente zeigt, vielleicht kann man da was ausnutzen.
-
std::remove gibt auch einen iterator zurück, der auf das Ende der verbleibenden Elemente zeigt, vielleicht kann man da was ausnutzen.
Ah, gute Idee. Das hilft mir wahrscheinlich schon.
Danke
Panke
-
-
Was "aha!" sagen will ist, dass remove von alleine kein Element löscht. Dafür gibt es erase.
-
KPC schrieb:
Was "aha!" sagen will ist, dass remove von alleine kein Element löscht. Dafür gibt es erase.
Oder besser: das erase-remove-Idiom.
vec.erase(remove(vec.begin(), vec.end(), value), vec.end());Das std::remove Elemente nicht wirklich entfernt liegt daran, dass dieser Algorithmus keinen Zugriff auf den Container hat und damit natürlich auch keine Möglichkeit aus selbigen zu löschen. Das gilt übrigens für alle Standardalgorithmen, die auf Sequenzen arbeiten und es ist sehr wichtig, dass man diesen Umstand genau versteht, andernfalls wird man Probleme beim Einsatz der STL bekommen.
std::remove ordnet die übergebene Sequenz so an, dass die nicht zu entfernenden Elemente am Beginn der Sequenz liegen und liefert einen Iterator auf das letzte "nicht entfernte" Element.
Eine Sequenz [begin, end) wird also so unterteilt, dass
* [begin, newEnd) alle Werte != value enthält (also die, die nicht entfernt werden sollen)
* [newEnd, end) enthält die "entfernten" Elemente in einer unspezifizierten Reiehenfolge (genaugenommen sind nicht mal die Werte der Elemente festgelegt).Die Anzahl der Elemente in der gesamten Sequenz bleibt dabei unverändert.
Mit dem erase-remove-Idiom erreicht man genau das Gewünschte: nachher enthält der Container nur noch genau die Elemente, die nicht entfernt werden sollten.
-
Jau, danke.
-
Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Rund um die Programmierung in das Forum C++ verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.