Ich habe einen std :: vector <int> und möchte das n-te Element löschen. Wie mache ich das?
std::vector<int> vec;
vec.Push_back(6);
vec.Push_back(-17);
vec.Push_back(12);
vec.erase(???);
Um ein einzelnes Element zu löschen, können Sie Folgendes tun:
std::vector<int> vec;
vec.Push_back(6);
vec.Push_back(-17);
vec.Push_back(12);
// Deletes the second element (vec[1])
vec.erase(vec.begin() + 1);
Oder, um mehrere Elemente gleichzeitig zu löschen:
// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);
Die Löschmethode von std :: vector ist überlastet, sodass der Aufruf wahrscheinlich klarer ist
vec.erase(vec.begin() + index);
wenn Sie nur ein einzelnes Element löschen möchten.
template <typename T>
void remove(std::vector<T>& vec, size_t pos)
{
std::vector<T>::iterator it = vec.begin();
std::advance(it, pos);
vec.erase(it);
}
Die erase
-Methode wird auf zwei Arten verwendet:
Einzelne Elemente löschen:
vector.erase( vector.begin() + 3 ); // Deleting the fourth element
Auswahl von Elementen löschen:
vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
Die Funktion erase
funktioniert eigentlich für zwei Profile:
Einzelne Elemente entfernen
iterator erase (iterator position);
Einen Bereich von Elementen entfernen
iterator erase (iterator first, iterator last);
Da std :: vec.begin () den Beginn des Containers markiert, und wenn wir das i-te Element in unserem Vektor löschen möchten, können wir Folgendes verwenden:
vec.erase(vec.begin() + index);
Wenn Sie genau hinschauen, ist vec.begin () nur ein Zeiger auf die Startposition unseres Vektors. Wenn Sie den Wert von i addieren, wird der Zeiger auf die Position i erhöht, sodass wir auf den Zeiger auf das ith-Element zugreifen können:
&vec[i]
So können wir schreiben:
vec.erase(&vec[i]); // To delete the ith element
Wenn Sie einen ungeordneten Vektor haben, können Sie die Tatsache ausnutzen, dass er ungeordnet ist und etwas verwenden, das ich von Dan Higgins bei CPPCON gesehen habe
template< typename TContainer >
static bool EraseFromUnorderedByIndex( TContainer& inContainer, size_t inIndex )
{
if ( inIndex < inContainer.size() )
{
if ( inIndex != inContainer.size() - 1 )
inContainer[inIndex] = inContainer.back();
inContainer.pop_back();
return true;
}
return false;
}
Da die Reihenfolge der Listen keine Rolle spielt, nehmen Sie einfach das letzte Element in der Liste und kopieren Sie es über dem Element, das Sie entfernen möchten, und platzieren Sie das letzte Element.
Wenn Sie mit großen Vektoren arbeiten (Größe> 100.000) und viele Elemente löschen möchten, würde ich Folgendes empfehlen:
int main(int argc, char** argv) {
vector <int> vec;
vector <int> vec2;
for (int i = 0; i < 20000000; i++){
vec.Push_back(i);}
for (int i = 0; i < vec.size(); i++)
{
if(vec.at(i) %3 != 0)
vec2.Push_back(i);
}
vec = vec2;
cout << vec.size() << endl;
}
Der Code nimmt jede Zahl in vec, die nicht durch 3 geteilt werden kann, und kopiert sie in vec2. Danach kopiert es vec2 in vec. Es ist ziemlich schnell. Für die Verarbeitung von 20.000.000 Elementen benötigt dieser Algorithmus nur 0,8 Sekunden!
Ich habe das gleiche mit der Erase-Methode gemacht, und es dauert sehr viel Zeit:
Erase-Version (10k elements) : 0.04 sec
Erase-Version (100k elements) : 0.6 sec
Erase-Version (1000k elements): 56 sec
Erase-Version (10000k elements): ...still calculating (>30 min)
Um ein Element zu löschen, gehen Sie folgendermaßen vor:
// declaring and assigning array1
std:vector<int> array1 {0,2,3,4};
// erasing the value in the array
array1.erase(array1.begin()+n);
Für eine umfassendere Übersicht besuchen Sie: http://www.cplusplus.com/reference/vector/vector/erase/
Ich schlage vor, dies zu lesen, da ich glaube, dass dies das ist, wonach Sie suchen. https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom
Wenn Sie zum Beispiel verwenden
vec.erase(vec.begin() + 1, vec.begin() + 3);
sie werden das n-te Element des Vektors löschen, aber wenn Sie das zweite Element löschen, werden alle anderen Elemente des Vektors verschoben und die Vektorgröße wird -1 sein. Dies kann problematisch sein, wenn Sie einen Vektor durchlaufen, da die Vektorgröße () abnimmt. Wenn Sie ein Problem mit diesem angegebenen Link haben, wird empfohlen, den vorhandenen Algorithmus in der Standard-C++ - Bibliothek zu verwenden. und "remove" oder "remove_if".
Hoffe das hat geholfen
Wie wäre es damit?
void squeeze(vector<int> &v)
{
int j = 0;
for (int i = 1; i < v.size(); i++)
if (v[i] != v[j] && ++j != i)
v[j] = v[i];
v.resize(j + 1);
}
dies ist eine weitere Möglichkeit, dies zu tun, wenn Sie ein Element löschen möchten, indem Sie es mit seinem Wert in vector finden.
vector<int> ar(n);
ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array));
es wird Ihren Wert von hier entfernen .. danke
Die vorherigen Antworten gehen davon aus, dass Sie immer einen signierten Index haben. Leider verwendet std::vector
size_type
für die Indizierung und difference_type
für die Iterator-Arithmetik, sodass sie nicht zusammenarbeiten, wenn "-Wconversion" und Freunde aktiviert sind. Dies ist eine weitere Möglichkeit, die Frage zu beantworten, während Sie sowohl signiert als auch unsigniert arbeiten können:
Zu entfernen:
template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
void remove(std::vector<T> &v, I index)
{
const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
v.erase(iter);
}
Nehmen:
template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
T take(std::vector<T> &v, I index)
{
const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
auto val = *iter;
v.erase(iter);
return val;
}
der schnellste Weg (für Programmierwettbewerbe nach Zeitaufwand () = konstant)
kann 100M Einzelteil in 1 Sekunde löschen;
vector<int> it = (vector<int>::iterator) &vec[pos];
vec.erase(it);
und am besten lesbar: vec.erase(vec.begin() + pos);