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

C++ Discussion :

set : recherche count() selon une fonction compare() différente de emplace()


Sujet :

C++

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    Février 2013
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Février 2013
    Messages : 154
    Points : 105
    Points
    105
    Par défaut set : recherche count() selon une fonction compare() différente de emplace()
    Bonjour,

    Alors voilà l'histoire.

    J'ai une structure T...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    struct T
    {
                int x; 
                int y;
    };
    ... et un set de T, triés selon x :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct Compare
    {
                bool operator() (T a, T b) const
                {
                    return (a.x < b.x);
                }
    };
     
    std::set<T,Compare> set;
    J'aimerais que les éléments soient triés selon x, mais je voudrais aussi pouvoir chercher un élément dans mon set en fonction de y, sans avoir à faire une recherche de complexité N.

    Étant donné que dans mon programme, tous les T que j'ajoute ont un y différent, je me dis qu'il y a un petit truc à faire au niveau de la fonction de Compare. Pour l'instant j'en suis à quelque chose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    bool operator() (T a, T b) const
    {
    if (a.y != b.y)
    return (a.x < b.x);
    else
    return (a.y < b.y);
    }
    Cela marche.. À peu près :

    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
     
    T a = {4,6};
            T b = {1,3};
            T d = {7,9};
     
            set.emplace(a);
            set.emplace(b);
            set.emplace(d);
     
            T tmp;
            tmp.y = 3;
     
            if (set.count({0,3}))
                std::cout << "foo";
     
      if (set.count({10,3}))
                std::cout << "bar";
    Output : foo.

    Le résultat dépend donc de la valeur x du T que je cherche, ainsi que des valeurs x déjà présentes dans le set (alors que seul le y m'intéresse), mais je ne comprends pas trop quelle valeur de x me permettrait d'obtenir le résultat que je veux, à chaque fois.

    Any idea ?
    "There should be no boundaries to human endeavor" - Hawking
    Retrouvez moi sur GitHub : https://github.com/JeanLouisMassei

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Malheureusement pour toi, la classe std::set ne permet que de trier les éléments qu'elle contient selon un ordre défini par le comparateur utilisé.

    Si tu veux pouvoir accéder aux mêmes éléments selon un ordre différent, la solution passe par le fait... de créer un autre set avec un autre ordre de tri et contenant les mêmes éléments. C'est parfois possible, mais rarement le meilleur moyen d'obtenir ce que tu cherches

    N'oublie en outre pas que, comme les éléments sont la clé dans un set, il est impossible de modifier un éléments de la collection sans passer par le fait de retirer l'élément, le modifier et le replacer dans le set une fois modifié

    Sinon, tu pourrais te tourner vers boost::bimap qui devrait répondre à tes besoins
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    Février 2013
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Février 2013
    Messages : 154
    Points : 105
    Points
    105
    Par défaut
    Héhé, oui je sais bien tout ça

    Mais du coup, comment expliquer que count() retourne parfois vrai, alors que l'élément n'est pas dans le set ?
    "There should be no boundaries to human endeavor" - Hawking
    Retrouvez moi sur GitHub : https://github.com/JeanLouisMassei

  4. #4
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Parce que le comparateur est foireux.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a = {2,1}
    b = {3,1}
     
    a < b < a

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur du dimanche
    Inscrit en
    Février 2013
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur du dimanche

    Informations forums :
    Inscription : Février 2013
    Messages : 154
    Points : 105
    Points
    105
    Par défaut
    Ah. Ah ben oui

    Merci pour vos réponses ! Je crois que je vais partir sur une recherche N, je n'ai pas installé boost sur mon ordi (oui, je devrais )
    "There should be no boundaries to human endeavor" - Hawking
    Retrouvez moi sur GitHub : https://github.com/JeanLouisMassei

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 16/10/2010, 18h07
  2. Réponses: 4
    Dernier message: 05/03/2009, 16h55
  3. Réponses: 2
    Dernier message: 17/06/2008, 12h08
  4. retourner un count() par une fonction PL/pgSQL ?
    Par ctobini dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 22/05/2007, 14h12

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