116 votes

L'effacement d'éléments à partir d'un vecteur

Je veux effacer un élément à partir d'un vecteur à l'aide de la méthode d'effacement. Mais le problème, c'est que l'élément n'est pas garanti pour se produire qu'une seule fois dans le vecteur. Il peut être présent plusieurs fois et j'ai besoin d'effacer tous les d'eux. Mon code ressemble à ça:

void erase(std::vector<int>& myNumbers_in, int number_in)
    {
        std::vector<int>::iterator iter = myNumbers_in.begin();
        std::vector<int>::iterator endIter = myNumbers_in.end();
        for(; iter != endIter; ++iter)
        {
        	if(*iter == number_in)
        	{
        		myNumbers_in.erase(iter);
        	}
        }

    }


    int main(int argc, char* argv[])
    {
        std::vector<int> myNmbers;
        for(int i = 0; i < 2; ++i)
        {
        	myNmbers.push_back(i);
        	myNmbers.push_back(i);
        }

        erase(myNmbers, 1);


        return 0;
    }

Ce code évidemment se bloque parce que je suis l'évolution de la fin du vecteur lors de l'itération à travers elle. Quelle est la meilleure façon d'atteindre cet objectif ? c'est à dire est-il un moyen de le faire sans une itération à travers le vecteur à plusieurs reprises ou de la création d'un plus copie du vecteur?

197voto

Motti Points 32921

Utiliser le supprimer/effacer idiome:

std::vector<int>& vec = myNumbers; // use shorter name
vec.erase(std::remove(vec.begin(), vec.end(), number_in), vec.end());

Ce qui se passe c'est qu' remove compacte les éléments qui diffèrent de la valeur à supprimer (number_in) au début de l' vector et renvoie l'itérateur pour le premier élément, après qu'gamme. Ensuite, erase supprime ces éléments (qui est la valeur n'est spécifiée).

64voto

dalle Points 9083

Appel erase permet d'invalider les itérateurs, vous pouvez utiliser:

void erase(std::vector<int>& myNumbers_in, int number_in)
{
    std::vector<int>::iterator iter = myNumbers_in.begin();
    while (iter != myNumbers_in.end())
    {
        if (*iter == number_in)
        {
            iter = myNumbers_in.erase(iter);
        }
        else
        {
           ++iter;
        }
    }

}

Ou vous pourriez utiliser std::remove_if avec un foncteur et std::vector::erase:

struct Eraser
{
    Eraser(int number_in) : number_in(number_in) {}
    int number_in;
    bool operator()(int i) const
    {
        return i == number_in;
    }
};

std::vector<int> myNumbers;
myNumbers.erase(std::remove_if(myNumbers.begin(), myNumbers.end(), Eraser(number_in)), myNumbers.end());

Au lieu d'écrire votre propre foncteur dans ce cas vous pouvez utiliser les std::remove:

std::vector<int> myNumbers;
myNumbers.erase(std::remove(myNumbers.begin(), myNumbers.end(), number_in), myNumbers.end());

4voto

Laserallan Points 5500

Selon pourquoi vous faites cela, à l'aide d'un std::set peut-être une meilleure idée que std::vector.

Il permet à chaque élément se produire qu'une seule fois. Si vous ajouter plusieurs fois, il n'y aura qu'une seule instance pour effacer toute façon. Cela rendra l'opération d'effacement trivial. L'opération d'effacement aura également moins de temps à la complexité que sur le vecteur, cependant, l'ajout d'éléments est plus lent sur l'ensemble de sorte qu'il pourrait ne pas être un avantage.

Bien sûr, cela ne fonctionnera pas si vous êtes intéressé par le nombre de fois qu'un élément a été ajouté à votre vecteur ou l'ordre des éléments ont été ajoutés.

-1voto

Burkhard Points 6734

Vous pourriez commencer à partir de la fin ou de la mise à jour de la fin quand un élément est effacé.

Il ressemblerait à quelque chose comme ceci:

void erase(std::vector<int>& myNumbers_in, int number_in)
    {
        std::vector<int>::iterator iter = myNumbers_in.begin();
        std::vector<int>::iterator endIter = myNumbers_in.end();
        for(; iter != endIter; ++iter)
        {
                if(*iter == number_in)
                {
                        myNumbers_in.erase(iter);
                        endIter = myNumbers_in.end();
                }
        }

    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X