IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SL & STL C++ Discussion :

Compter le nombre de valeurs unqiues


Sujet :

SL & STL C++

  1. #1
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut Compter le nombre de valeurs unqiues
    Je cherche à compter un nombre de valeurs uniques (les données d'origine sont dans un tableau de tableaux, 2 std::vector<> imbriqués quoi).

    Je me propose très simplement de créer un std::set<> en parcourant mon tableau puis en lire la taille.

    Y-a-t-il mieux, plus performant ? Par exemple, créer un std::vector<>, le trier, puis compter les valeurs uniques.

    Merci !

  2. #2
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    Que veux-tu dire par "valeur unique" ?
    Sinon, tu peux jeter un coup d'oeil du côté de la fonction std::unique (en-tête <algorithm>, cf. lien dans ma signature).

  3. #3
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    5, 2, 3, 5, 4, 2, 4, 7, 1

    Distinctes si tu préfères. Dans cet exemple il y a 6 valeurs distinctes parmi un total de 9.

    std::unique(), je vais regarder.
    Ceci dit, l'usage de std::set<> est une solution comme je le disais, mais est-ce "bien" ?

  4. #4
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Je viens de voir std::unique(). Il en fait trop dans mon cas, j'ai juste besoin de les compter. La modification éventuel ajoute en complexité inutile.
    Mais c'est une fonction intéressante à retenir (sauf que conserver le tri, indispensable avant l'appel de la fonction, n'eut pas été surperflu en sortie).

    PS:
    Dans ta documentation sur <algorithm> (très intéressante d'ailleurs) tu ne parles pas des fonctions "heap". Un petit tuto à leur sujet serait pas mal

  5. #5
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Salut,
    tu pourrai te faire un foncteur pour cela.



    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    #include <algorithm>
    #include <iostream>
    #include <vector>  
     #include <set>  
     
    template <class T>
    struct CombienUnique
    	{
    	CombienUnique(){};
    	//constructeur par recopie bidon qui eviter de recopier le set.
    	//swap les contenu des set
    	CombienUnique(CombienUnique<T> & CU)
    		{
    		std::swap(myUnique,CU.myUnique);
    		}
    	void operator()(const T & t) {myUnique.insert(t);}
    	int GetNbUnique() {return myUnique.size();};
     
    	std::set<T> myUnique;
    };
     
    int main(int argc, char** argv)
    {
    //initialisation
    std::vector<int> myvect;
    myvect.push_back(1);
    myvect.push_back(4);
    myvect.push_back(10);
    myvect.push_back(1);
    myvect.push_back(20);
    myvect.push_back(1);
    myvect.push_back(10);
     
    //récupère les uniques
    CombienUnique<int> myFoncteur = std::for_each(myvect.begin(),myvect.end(),CombienUnique<int>());
    //affichage
    std::cout<<"Nb unique : "<<myFoncteur.GetNbUnique()<<std::endl;
    std::copy(myFoncteur.myUnique.begin(),myFoncteur.myUnique.end(),std::ostream_iterator<int> (std::cout,"\n"));
     
    return 0;
    }

  6. #6
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    j'en suis


    Bon, en attendant d'approfondir <algorithm> je vais me contenter d'un plus classique
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    int main(int argc, char** argv)
    {
    //initialisation
    std::vector<int> myvect;
    myvect.push_back(1);
    myvect.push_back(4);
    myvect.push_back(10);
    myvect.push_back(1);
    myvect.push_back(20);
    myvect.push_back(1);
    myvect.push_back(10);
     
    //récupère les uniques
    std::set<int> s;
    {
    for (std::vector<int>::iterator it=myvect.begin();it!=myvect.end();it++)
    	s.insert(*it);
    }
    //affichage
    cout<< "Nb unique : " << s.size() << endl;
    {
    for (std::set<int>::iterator it=s.begin();it!=s.end();it++)
    	cout << *it << endl;
    }
     
    return 0;
    }

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par camboui Voir le message
    j'en suis


    Bon, en attendant d'approfondir <algorithm> je vais me contenter d'un plus classique
    Au moins tu as compris mon code

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    EN faite, le foncteur n'est pas tellement necessaire ici. C'est vrai
    mais bon je m'entraine

    tu as beaucoup plus rapide pour initialiser ton set :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::set<int> s(myvect.begin(),myvect.end());

    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::set<int> s
    .
    .
    .
    s.clear();
    s.insert(myvect.begin(),myvect.end());

  9. #9
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Je vois que tu t'éclates avec les foncteurs MonGaulois !

    Effectivement, un petit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::set<int> s(myvect.begin(),myvect.end());
    std::cout << s.size() << std::endl;
    permet de compter les uniques...
    Ce ne sera pas l'algo le plus rapide, mais au moins ça marche bien ! :-)

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par poukill Voir le message
    Je vois que tu t'éclates avec les foncteurs MonGaulois !

    Effectivement, un petit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::set<int> s(myvect.begin(),myvect.end());
    std::cout << s.size() << std::endl;
    permet de compter les uniques...
    Ce ne sera pas l'algo le plus rapide, mais au moins ça marche bien ! :-)
    ben, en y réfléchissant je ne voit pas comment faire plus rapide....

  11. #11
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Plus je réfléchis, plus je me dis que tu as raison ...

  12. #12
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Si on ne travaille pas par ajout successifs, en incrémental, mais une seules fois sur un bloc de données, et que les données sont légères, comme ici, je suis parès à parier qu'un sort sur un vector suivi d'un parcours pour compter sera plus rapide qu'une copie dans un set. Ne serait-ce que parce que la localité de la mémoire est meilleure.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  13. #13
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Une version bien plus couteuse mais qui permet d'élargir ta connaissance des algorithmes standards se baserait sur std::count_if

  14. #14
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Si on ne travaille pas par ajout successifs, en incrémental, mais une seules fois sur un bloc de données, et que les données sont légères, comme ici, je suis parès à parier qu'un sort sur un vector suivi d'un parcours pour compter sera plus rapide qu'une copie dans un set. Ne serait-ce que parce que la localité de la mémoire est meilleure.
    peut etre sur un petit vector. mais aprés...
    Je sais pô.
    Toute facon il me semble qu'il ne veut pas modifier sont vector

  15. #15
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Effectivement, si le vector ne doit pas être modifié, il faudra en faire une copie, alors...

  16. #16
    Membre éclairé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Si on ne travaille pas par ajout successifs, en incrémental, mais une seules fois sur un bloc de données, et que les données sont légères, comme ici, je suis parès à parier qu'un sort sur un vector suivi d'un parcours pour compter sera plus rapide qu'une copie dans un set. Ne serait-ce que parce que la localité de la mémoire est meilleure.
    Ah, enfin une réponse à ma question initiale Y-a-t-il mieux qu'utiliser un std::set<> ?

    Pour rappel, je dois initialiser les valeurs du set/vector une par une. Lisez mon premier post, les donnés d'origine sont dans un tableau de tableaux (et pas nécessairement de même longueur).

    Je peux vous donner le problème à la base
    J'ai un graphe duquel j'extrais plusieurs chemins entre deux sommets. Jusqu'à présent les clients paient le nombre total de sommets visités par l'ensemble des chemins. Bien sur, de nombreux sommets se retrouvent dans plusieurs chemins différents et les clients ne veulent pas payer pour tous ces doublons. Je dois donc connaitre le nombre de sommets uniques de l'ensemble des chemins. Le tableau de tableaux est donc un tableau de chemins, chaque chemin étant un tableau de sommets.

    Voilà, voilà, à vos méninges sachant que j'ai deux solutions proposées jusqu'à présent:
    1) insertion des sommets un par un dans un std::set, puis size().
    2) insertion des sommets un par un dans un std::vector, puis sort() et comptage.

  17. #17
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par camboui Voir le message
    Ah, enfin une réponse à ma question initiale Y-a-t-il mieux qu'utiliser un std::set<> ?
    Sa methode est dans le cas ou le vector est déjà initialisé.
    Sinon ben le set gagne. J'en suis quasi sur

  18. #18
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    Sa methode est dans le cas ou le vector est déjà initialisé.
    Sinon ben le set gagne. J'en suis quasi sur
    Le seul point dont je suis quasi sur, c'est que seule une mesure (de préférence avec un jeu de données proche du jeu réel) permettra de départager les solutions.

    Maintenant, sur le plan feeling et devinette et discussion de comptoir, je ne vois rien à l'avantage de set dans la description du problème. Là il en aurait certainement, c'est s'il fallait par exemple ajuster souvent le coût en ajoutant un nouveau trajet à ceux pris en compte.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment compter le nombre de valeur différentes
    Par chelmi95 dans le forum IHM
    Réponses: 3
    Dernier message: 02/05/2008, 18h02
  2. [TCD]Compter le nombre de valeurs distinctes
    Par xaramelaz dans le forum Excel
    Réponses: 2
    Dernier message: 16/08/2007, 20h37
  3. Compter le nombre de valeur en rouge
    Par marsupilami34 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 25/05/2007, 14h18
  4. Compter le nombre de valeurs différentes
    Par solorac dans le forum Excel
    Réponses: 6
    Dernier message: 21/04/2007, 16h13
  5. [Excel] Compter le nombre de valeurs
    Par Malach dans le forum Excel
    Réponses: 3
    Dernier message: 06/04/2006, 00h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo