Comment effacer un élément de std:: vector par index?
j'ai un std::vector, et je veux supprimer le n'ème élément. Comment dois-je faire?
std::vector<int> vec;
vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);
vec.erase(???);
10 réponses
supprimer un seul élément, vous pouvez faire:
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);
Ou, pour supprimer plus d'un élément à la fois:
// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);
la méthode d'effacement sur std:: vector est surchargée, il est donc probablement plus clair d'appeler
vec.erase(vec.begin() + index);
quand vous ne voulez effacer un seul élément.
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);
}
la méthode erase
sera utilisée de deux façons:
-
Effacement d'un seul élément:
vector.erase( vector.begin() + 3 ); // Deleting the fourth element
-
l'Effacement de la gamme d'éléments:
vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
en fait, la fonction erase
fonctionne pour deux profils:
-
enlèvement d'un seul élément
iterator erase (iterator position);
-
suppression d'une série d'éléments
iterator erase (iterator first, iterator last);
Depuis std::vector.begin() marque le début du conteneur et si nous voulons supprimer le ième élément du vecteur, on peut utiliser:
vec.erase(vec.begin() + index);
si vous regardez de près, vec.begin() n'est qu'un pointeur vers la position de départ de notre vecteur et l'ajout de la valeur de i augmente le pointeur vers la position de i, donc nous pouvons accéder au pointeur vers le ième élément par:
&vec[i]
pour que nous puissions écrire:
vec.erase(&vec[i]); // To delete the ith element
si vous avez un vecteur non-classé, vous pouvez profiter du fait qu'il est non-classé et utiliser quelque chose que J'ai vu de Dan Higgins à 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;
}
comme l'ordre de la liste n'a pas d'importance, il suffit de prendre le dernier élément de la liste et de le copier sur le dessus de l'élément que vous voulez supprimer, puis pop et supprimer le dernier élément.
si vous travaillez avec de grands vecteurs (taille > 100.000) et que vous voulez supprimer beaucoup d'éléments, je vous recommande de faire quelque chose comme ceci:
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;
}
le code prend tous les nombres de vec qui ne peuvent pas être divisés par 3 et le copie à vec2. Ensuite, il copie vec2 dans vec. Il est assez rapide. Pour traiter 20 000 000 d'éléments cet algorithme ne prend que 0,8 sec!
j'ai fait la même chose avec la méthode d'effacement, et ça prend beaucoup de temps:
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)
pour supprimer un élément, utiliser la manière suivante:
// declaring and assigning array1
std:vector<int> array1 {0,2,3,4};
// erasing the value in the array
array1.erase(array1.begin()+n);
Pour un plus large aperçu , vous pouvez visiter: http://www.cplusplus.com/reference/vector/vector/erase/
les réponses précédentes supposent que vous toujours avez un index signé. Malheureusement, std::vector
utilise size_type
pour l'indexation, et difference_type
pour l'arithmétique itérative, de sorte qu'ils ne fonctionnent pas ensemble si vous avez"- Wconversion " et amis activés. C'est une autre façon de répondre à la question, tout en étant capable de traiter à la fois signé et non signé:
supprimer:
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);
}
à prendre:
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;
}
voici une autre façon de le faire si vous voulez supprimer un élément en le trouvant avec sa valeur dans vector,vous avez juste besoin de le faire sur vector.
vector<int> ar(n);
ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array));
il va supprimer votre valeur d'ici. merci