Tengo un std :: vector < int>, y quiero eliminar el n-ésimo elemento. ¿Cómo puedo hacer eso?¿Cómo borro un elemento de std :: vector <> por índice?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
Tengo un std :: vector < int>, y quiero eliminar el n-ésimo elemento. ¿Cómo puedo hacer eso?¿Cómo borro un elemento de std :: vector <> por índice?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
Para eliminar un solo elemento, que podría hacer:
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);
O, para eliminar más de un elemento a la vez:
// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);
Tenga en cuenta que el 'operador +' binario es __not__ necesariamente definido para iteradores en otros tipos de contenedor, como 'list
está indicando que" +1 "es el primer elemento myVector [0] o la posición real myVector [1] –
it + 1 es un elemento con id 1, p. ej. contenedor [1]. primer elemento es +0. Vea el comentario a continuación ... – Nick
El método de borrado en std :: vector está sobrecargado, por lo que probablemente sea más claro llamar a
vec.erase(vec.begin() + index);
cuando solo quiere borrar un solo elemento.
Esto no es bueno si solo tiene un elemento ... no verifica el índice ... – alap
Pero ese problema aparece sin importar cuántos elementos tenga. –
si solo hay un elemento, el índice es 0, y entonces obtienes 'vec.begin()' que es válido. –
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, lo que hace que la función sea mejor que: 'plantilla
@JoeyvG: Dado que un 'vector
Esta es la mejor respuesta, ya que también se aplica a otros formatos de contenedor. También podría usar std :: next(). – Bim
El método erase
se puede utilizar de dos maneras:
Borrado solo elemento:
vector.erase(vector.begin() + 3); // Deleting the third element
gama de borrado de elementos:
vector.erase(vector.begin() + 3, vector.begin() + 5); // Deleting from third element to fifth element
Si se trabaja con vectores grandes (tamaño> 100.000) y quiere eliminar una gran cantidad de elementos, que recomendaría a hacer algo como esto:
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;
}
El código toma cada número en el vec que no puede ser dividido por 3 y lo copia a vec2. Luego copia vec2 en vec. Es bastante rápido ¡Para procesar 20,000,000 de elementos, este algoritmo solo toma 0.8 segundos!
me hizo lo mismo con el borrado de un método, y se necesita mucho, mucho tiempo:
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)
¿Cómo responde esto la pregunta? –
¡Interesante, pero no relevante para la pregunta! – Roddy
¿No será más rápido un algoritmo in situ? – user202729
En realidad, la función erase
obras para dos perfiles:
Extracción de una solo elemento
iterator erase (iterator position);
Extracción de una gama de elementos
iterator erase (iterator first, iterator last);
Desde std :: vec.begin() marca el inicio del contenedor y si queremos eliminar el elemento i en nuestro vector, podemos utilizar:
vec.erase(vec.begin() + index);
Si mira de cerca, vec.begin() es sólo un puntero a la posición de partida de nuestro vector y añadiendo el valor de i que se incrementa el puntero de i posición, así que en vez podemos acceder al puntero al elemento i por:
&vec[i]
Así podemos escribir:
vec.erase(&vec[i]); // To delete the ith element
para eliminar un elemento de uso de la siguiente manera:
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);
para más amplia visión se puede visitar: - http://www.cplusplus.com/reference/vector/vector/erase/
Las respuestas anteriores asumen que siempre tienen un índice firmado. Tristemente, std::vector
usa size_type
para indexar, y difference_type
para aritmética de iterador, por lo que no funcionan juntos si tiene "-Wconversion" y amigos habilitados. Esta es otra manera de responder a la pregunta, mientras que ser capaz de manejar tanto con y sin signo:
Para retirar:
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);
}
Tomar:
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;
}
Si usted tiene un vector desordenada que puede aprovechar el hecho de que está desordenado y usar algo que vi de Dan Higgins en 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;
}
Dado que el orden de la lista no importa, simplemente tome el último elemento de la lista y cópielo en la parte superior del artículo que desea eliminar, y luego haga clic y elimine el último elemento.
Considere el uso de std :: deque, que proporciona inserción y eliminación en ambos extremos. – Dario
No, no considere usar deque simplemente porque es posible que desee eliminar un elemento, eso es realmente un consejo pobre. Hay una gran cantidad de razones por las que es posible que desee utilizar deque o vector. Es cierto que eliminar un elemento de un vector puede ser costoso, especialmente si el vector es grande, pero no hay motivo para pensar que un deque sea mejor que un vector del ejemplo de código que acaba de publicar. – Owl
Por ejemplo, si tiene una aplicación gráfica donde muestra una "lista" de cosas donde inserta/quita cosas de manera interactiva, considere ejecutar la lista 50-100 veces por segundo para mostrarlas, y agregar/eliminar cosas algunas veces cada minuto. Entonces, implementar la "lista" como vector es probablemente una mejor opción en términos de eficiencia total. –