Je regardais la documentation de l'API pour le vecteur stl, et j'ai remarqué qu'il n'y avait aucune méthode sur la classe vector qui permettait de supprimer un élément avec une certaine valeur. Cela semble être une opération courante, et il semble étrange qu'il n'y ait pas de méthode intégrée pour le faire.
145
Réponses:
std::remove
n'efface pas réellement l'élément du conteneur, mais il renvoie le nouvel itérateur de fin qui peut être passé àcontainer_type::erase
pour effectuer la suppression REELLE des éléments supplémentaires qui se trouvent maintenant à la fin du conteneur:la source
vec.end()
garantie d'être la même de chaque côté de l'appel àstd::remove
? Il me semble que la lecture d'autres parties du Web comme celle-ci est sûre, mais cela devrait être clairement indiqué.vec.end()
n'a pas besoin d'être le même; il doit juste être correct (ce qui est le cas).vec.end()
doit être identique, mais cestd::remove
n'est pas grave car cela ne change rien. S'il le modifiait (et invalide l'ancienne valeur), alors il y aurait un problème: l'ordre d'évaluation des paramètres n'est pas spécifié et donc vous ne sauriez pas si la secondevec.end()
est toujours valide au moment où elle est utilisée. La raison pour laquelle c'est la même chose est simple,std::remove
ne change pas la taille du conteneur, cela déplace simplement le contenu.std::remove
avec un seul argument; c'est çaconst char *_Filename
. Quelle méthode dois-je appeler?remove
qui supprime un fichier. Vous devez inclure<algorithm>
pour accéder à la version deremove
qui traite des conteneurs.Si vous souhaitez supprimer un élément, ce qui suit sera un peu plus efficace.
ou vous pouvez éviter les frais généraux liés au déplacement des articles si la commande ne compte pas pour vous:
la source
Utilisez la méthode globale std :: remove avec l'itérateur de début et de fin, puis utilisez std :: vector.erase pour supprimer réellement les éléments.
Liens de documentation
std :: remove http://www.cppreference.com/cppalgorithm/remove.html
std :: vector.erase http://www.cppreference.com/cppvector/erase.html
Merci à Jim Buck d'avoir signalé mon erreur.
la source
Les autres réponses expliquent comment bien faire cela, mais j'ai pensé également souligner qu'il n'est pas vraiment étrange que ce ne soit pas dans l'API vectorielle: c'est une recherche inefficace et linéaire dans le vecteur de la valeur, suivie d'un tas de copier pour le supprimer.
Si vous effectuez cette opération de manière intensive, cela peut valoir la peine de considérer std :: set à la place pour cette raison.
la source
Si vous avez un vecteur non trié, vous pouvez simplement échanger avec le dernier élément vectoriel
resize()
.Avec un conteneur commandé, vous serez mieux avec
std::vector::erase()
. Notez qu'il y a unstd::remove()
défini dans<algorithm>
, mais cela ne fait pas réellement l'effacement. (Lisez attentivement la documentation).la source
Une solution plus courte (qui ne vous oblige pas à répéter le nom du vecteur 4 fois) serait d'utiliser Boost:
Voir http://www.boost.org/doc/libs/1_64_0/libs/range/doc/html/range/reference/algorithms/new/remove_erase.html
la source
À partir de C ++ 20 :
Une fonction non membre introduite
std::erase
, qui prend le vecteur et la valeur à supprimer comme entrées.ex:
la source
map::erase
!Voir aussi std :: remove_if pour pouvoir utiliser un prédicat ...
Voici l'exemple du lien ci-dessus:
la source
Si vous voulez le faire sans aucun supplément comprend:
la source
Vous pouvez utiliser deux méthodes pour effacer un élément en particulier. prenons un vecteur
1) Manière non efficace: bien que cela semble assez efficace mais ce n'est pas parce que la fonction d'effacement supprime les éléments et décale tous les éléments vers la gauche de 1. donc sa complexité sera O (n ^ 2)
2) Moyen efficace (RECOMMANDÉ) : Il est également connu sous le nom de ERASE - REMOVE idioms .
la sortie de l'algorithme de suppression est:
comme type de retour de remove est un itérateur vers la nouvelle extrémité de cette plage.
Utilisez maintenant la fonction d'effacement du vecteur pour supprimer des éléments de la nouvelle extrémité à l'ancienne extrémité du vecteur. Il faut un temps O (1).
donc cette méthode fonctionne en O (n)
la source
*
*
C ++ 20 fournit un moyen facile de le faire maintenant. Cela devient aussi simple que:
Vous devriez vérifier std :: erase et std :: erase_if .
Non seulement il supprimera tous les éléments de la valeur (ici '0'), mais il le fera avec une complexité de temps O (n) . Quel est le meilleur que vous puissiez obtenir.
Si votre compilateur ne prend pas en charge C ++ 20, vous devez utiliser l' idiome erase-remove :
la source