3 votes

Eléments répétés dans un std::vector

J'ai un std::vector et je veux vérifier tous les éléments qu'il contient. Si un certain élément apparaît plus d'une fois, je signale une erreur.

Voici comment je l'ai fait :

std::vector test;
test.push_back("YES");
test.push_back("YES");

for(int i = 0; i < test.size(); i++)
{
    if(test[i] > 1)
    {
        DCS_LOG_DEBUG("ERREUR AVEC LE COMPTEUR")
    }
}

Cela n'a pas fonctionné même si je sais comment compter en utilisant la méthode std::vector::count(). Mais je veux obtenir le décompte pour chaque élément, au lieu de tout compter... des idées ?

2voto

OmarOthman Points 751

Si vous ne vous souciez pas de l'espace supplémentaire, essayez de pousser les éléments dans un map. Chaque fois que vous trouvez votre élément déjà dans le map, vous pouvez signaler l'erreur directement.

map occurrences;

for (vector::const_iterator cit = test.begin(); cit != test.end(); ++cit)
    if ((++occurrences[*cit]) == 2)
        cout << "ERREUR"; // Vous pouvez même signaler quel élément est répété ici facilement, en utilisant *cit.

Notez que ce code émet correctement le message une seule fois par élément répété (même si l'élément est répété plusieurs fois), comme l'a intelligemment amendé Tony Delroy. Bien que cette méthode compte correctement l'occurrence de chaque chaîne de caractères dans toute la collection (ce qui peut être nécessaire), cette méthode est sujette à un débordement d'un int s'il y a 2^31 copies du même élément (ou plus). Vous pouvez utiliser un long long int à la place si tel est le cas et que vous voulez vraiment le décompte de chaque chaîne de caractères.

Si vous n'êtes pas intéressé par le décompte de chaque chaîne de caractères, une méthode encore plus efficace est d'utiliser un set, comme le suggère smerlin (car il ne maintient que la chaîne de caractères, pas une paire de chaîne de caractères et d'int comme le fait le map), réduisant ainsi les besoins en espace... et émettant le message d'erreur chaque fois que vous trouvez l'élément dans le set:

set occurrences;

for (vector::const_iterator cit = test.begin(); cit != test.end(); ++cit)
    if (false == occurrences.insert(*cit).second)
        cout << "ERREUR"; // Vous pouvez même signaler quel élément est répété ici facilement, en utilisant *cit.

Si vous voulez éliminer le problème avant qu'il ne se produise, insérez les éléments dans un set à la place. Il élimine automatiquement les doublons. Mais faites attention, les éléments dans un set sont triés, donc vous ne conservez pas l'ordre d'insertion. Si cela ne vous dérange pas, un set est bien meilleur, car la recherche en lui et la lecture des éléments dans un ordre trié sont beaucoup plus efficaces.

1voto

Une solution pourrait être d'utiliser deux boucles for.... Je pense que cela sera simple..

Par exemple:

std::vector test;
test.push_back("OUI");
test.push_back("OUI");

for(int i = 0; i < test.size(); i++)
{
    for(int j = 0; j < test.size(); j++)
    {
         if(i != j)
         {
              if(test[i] == test[j])
              {
                   DCS_LOG_DEBUG("ERREUR AVEC LE COMPTEUR")
              }
         }
    }
}

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