Ho uno std :: vector < int> e desidero eliminare l'elemento n'th. Come lo faccio?Come si cancella un elemento da std :: vector <> per indice?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
Ho uno std :: vector < int> e desidero eliminare l'elemento n'th. Come lo faccio?Come si cancella un elemento da std :: vector <> per indice?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
Per cancellare un singolo elemento, si potrebbe fare:
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);
Oppure, per eliminare più di un elemento alla volta:
// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);
Nota anche l'operatore binario '' è __not__ necessariamente definito per gli iteratori su altri tipi di contenitori, come 'lista
affermi che il" +1 "è il primo elemento di myVector [0] o la posizione attuale myVector [1] –
it + 1 è l'elemento con ID 1, ad es. contenitore [1]. il primo elemento è +0. Vedere il commento sotto ... – Nick
Il metodo di cancellazione su std :: vector è sovraccarico, quindi è probabilmente più chiaro chiamare
vec.erase(vec.begin() + index);
quando si desidera cancellare un singolo elemento.
Questo non va bene se si ha solo un elemento ... non si controlla l'indice ... – alap
Ma quel problema appare indipendentemente dal numero di elementi che si hanno. –
se c'è solo un elemento, l'indice è 0 e quindi si ottiene 'vec.begin()' che è valido. –
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);
}
Max, ciò che rende questa funzione migliore di: 'modello
@JoeyvG: Poiché un 'vector
Questa è la risposta migliore, poiché si applica anche ad altri formati di contenitore. Puoi anche usare std :: next(). – Bim
Procedimento erase
verrà utilizzato in due modi:
Cancellazione singolo elemento:
vector.erase(vector.begin() + 3); // Deleting the third element
gamma Cancellazione di elementi:
vector.erase(vector.begin() + 3, vector.begin() + 5); // Deleting from third element to fifth element
Se si lavora con i grandi vettori (dimensioni> 100.000) e da eliminare un sacco di elementi, mi sento di raccomandare a fare qualcosa di simile:
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;
}
Il codice prende ogni numero in vec che non può essere diviso per 3 e lo copia in vec2. Successivamente copia vec2 in vec. È piuttosto veloce Per elaborare 20.000.000 di elementi questo algoritmo impiega solo 0,8 sec!
Ho fatto la stessa cosa con la cancellazione metodo, e ci vuole un sacco di tempo:
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)
come risponde la domanda? –
Interessante, ma non pertinente alla domanda! – Roddy
Non sarà un algoritmo sul posto più veloce? – user202729
In realtà, la funzione erase
lavora per due profili:
Rimozione di un elemento singolo
iterator erase (iterator position);
Rimozione di un intervallo di elementi
iterator erase (iterator first, iterator last);
Dal std :: vec.begin() segna l'inizio di contenitore e, se vogliamo eliminare l'elemento i-esimo nel nostro vettore, possiamo usare:
vec.erase(vec.begin() + index);
Se guarda da vicino, vec.begin() è solo un puntatore alla posizione di partenza del nostro vettore e aggiungendo il valore di i ad esso incrementa il puntatore I POSIZIONE, così invece si può accedere al puntatore all'elemento i-esimo da:
&vec[i]
Così possiamo scrivere:
vec.erase(&vec[i]); // To delete the ith element
per eliminare un elemento di utilizzare il seguente modo:
1 // declaring and assigning array1
2 std:vector<int> array1 {0,2,3,4};
3
4 // erasing the value in the array
5 array1.erase(array1.begin()+n);
per più ampia panoramica si possono visitare: - http://www.cplusplus.com/reference/vector/vector/erase/
Le risposte precedenti presumono che tu sempre abbia un indice firmato. Purtroppo, std::vector
utilizza size_type
per l'indicizzazione e difference_type
per l'aritmetica di iteratore, quindi non funzionano insieme se si dispone di "-Wversion" e di amici abilitati. Questo è un altro modo per rispondere alla domanda, pur essendo in grado di gestire entrambi firmati e non firmati:
Per rimuovere:
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);
}
Per fare:
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;
}
Se si dispone di un vettore non ordinata si può trarre vantaggio dal fatto che non è ordinato e utilizzare qualcosa che ho visto da Dan Higgins a CPPCON
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;
}
Poiché l'ordine dell'elenco non ha importanza, basta prendere l'ultimo elemento nell'elenco e copiarlo sopra l'elemento superiore che si desidera rimuovere, quindi compila ed elimina l'ultimo elemento.
Considerare l'utilizzo di un codice std :: che fornisce l'inserimento e l'eliminazione a entrambe le estremità. – Dario
No, non considerare l'utilizzo di deque solo perché potresti voler eliminare un elemento, questo è un consiglio davvero scarso. C'è un sacco di motivi per cui potresti voler usare deque o vector. È vero che eliminare un elemento da un vettore può essere costoso, specialmente se il vettore è grande, ma non c'è motivo di pensare che un deque sarebbe meglio di un vettore dell'esempio di codice che hai appena postato. – Owl
Ad esempio, se si dispone di un'applicazione grafica in cui viene visualizzato un "elenco" di cose in cui si inseriscono/rimuovono le cose in modo interattivo, considerare di scorrere l'elenco da 50 a 100 volte al secondo per visualizzarle e aggiungere/rimuovere elementi a poche volte al minuto. Quindi implementare la "lista" come vettore è probabilmente una scelta migliore in termini di efficienza totale. –