c++ - recorrer - ¿Cómo borro un elemento de std:: vector<> por índice?
recorrer una lista c++ (10)
El método de erase
se utilizará de dos maneras:
Borrado de un solo elemento:
vector.erase( vector.begin() + 3 ); // Deleting the fourth element
Borrado de rango de elementos:
vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
Tengo un std :: vector <int>, y quiero eliminar el elemento n''th. ¿Cómo puedo hacer eso?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
El método de borrado en std :: vector está sobrecargado, por lo que probablemente sea más claro llamar
vec.erase(vec.begin() + index);
Cuando solo quieras borrar un solo elemento.
En realidad, la función de erase
funciona para dos perfiles:
Eliminando un solo elemento
iterator erase (iterator position);
Eliminando una gama de elementos.
iterator erase (iterator first, iterator last);
Ya que std :: vec.begin () marca el inicio del contenedor y si queremos eliminar el elemento i en nuestro vector, podemos usar:
vec.erase(vec.begin() + index);
Si observa detenidamente, vec.begin () es solo un puntero a la posición inicial de nuestro vector y agregar el valor de i incrementa el puntero a la posición i, por lo que podemos acceder al puntero al elemento i mediante:
&vec[i]
Para que podamos escribir:
vec.erase(&vec[i]); // To delete the ith element
Esta es una forma más de hacer esto si desea eliminar un elemento al encontrarlo con su valor en vector, solo necesita hacerlo en vector.
vector<int> ar(n);
ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array));
eliminará su valor desde aquí. Gracias
Las respuestas anteriores asumen que siempre tienes un índice firmado. Lamentablemente, std::vector
usa size_type
para la indexación, y size_type
para la aritmética de iteradores, por lo que no funcionan juntos si tiene "-Conversión" y amigos habilitados. Esta es otra forma de responder a la pregunta, mientras se puede manejar tanto firmado como sin firmar:
Para eliminar:
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;
}
Para eliminar un elemento utiliza de la siguiente manera:
// declaring and assigning array1
std:vector<int> array1 {0,2,3,4};
// erasing the value in the array
array1.erase(array1.begin()+n);
Para una descripción más amplia , puede visitar: http://www.cplusplus.com/reference/vector/vector/erase/
Para eliminar un solo elemento, puedes 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 bien, 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);
Si tiene un vector desordenado, 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 sobre la parte superior del elemento que desea eliminar, luego abra y elimine el último elemento.
Si trabaja con vectores grandes (tamaño> 100,000) y desea eliminar muchos elementos, le recomendarí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 todos los números de vec que no se pueden dividir por 3 y los copia a vec2. Luego se copia vec2 en vec. Es bastante rapido Para procesar 20,000,000 elementos, este algoritmo solo toma 0,8 segundos.
Hice lo mismo con el método de borrado, y lleva 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)
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);
}