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 :

Utilisation des set


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 134
    Par défaut Utilisation des set
    Bonjour.

    Voilà une journée que je me prend la tête avec des set, aussi, j'en appel à vous


    Alors voilà.
    J'ai les objets suivant
    • Une classe Tetra
    • Une classe Solution qui est un set de Tetra

    Une solution est composé de tetras, sans doublons, et j'aimerais qu'il soit automatiquement triés par le set

    voilà donc ce que j'ai fait pour mes tetras
    Tetra.h
    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
    class Tetra {
    public:
    	Tetra(ui s1, ui s2, ui s3, ui s4);
     
     
    	ui operator[] (ui ref) {return cases[ref];};
     
     
    	void set(ui s1, ui s2, ui s3, ui s4);
     
    	int getType()    { return type;}
    	ui getcase(ui i) { return cases[i];}
    	ui getX(ui i)    { return xcases[i];}
    	ui getY(ui i)    { return ycases[i];}
     
     
    private:
    	int findType();
     
    	ui cases[4];  // par ordre croissant
    	ui xcases[4]; // les coord x des cases
    	ui ycases[4]; // les coord y des cases
    	int type; // 5 differents (cf define)
     
    };
     
    struct triTetraCroissant
    { 
    	bool operator ()( Tetra & t1,  Tetra & t2) const 
    	{ 
    		return t1.getcase(0) < t2.getcase(0);
    	}
    };
    Vous aurez reconnus la structure qui est dans votre FAQ, mais je ne suis pas du tout sur qu'il faille la mettre ici ... c'est bon?


    Et voici ce que j'ai mis dans solution.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Solution {
    public:
    	Solution ();
    	int isOK();
     
    	int addTetra(Tetra);
     
     
    private:
    	std::set<Tetra> solution;
    	ui tetra_par_type[5];
     
     
    };
    et dans solution.cpp
    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
    int Solution::addTetra(Tetra tetra)
    {
    	if (tetra_par_type[ tetra.getType() -1] > 2)
    	{
    		return SOLUTION_INVALIDE;
    	}
    	// pair <Tetra, bool> p;
    	solution.insert(tetra);
    	// if (p.second) return SOLUTION_INVALIDE;
     
    	// if (solution.size() == 10) return SOLUTION_COMPLETE;
     
    	return SOLUTION_PARTIELLE;
     
    }
    Alors ce que j'essaie de faire :
    Quand on construit un objet Solution, son set est vide.
    Ensuite au fur et a mesure qu'on va analyser le problème, on va ajouter des Tetra à la solution (avec la méthode Solution::addTetra(Tetra tetra)), celle ci vérifie que le type du tétra est autorisé (car une solution valide doit respecter certains critère là dessus)
    Ensuite il ajoute le tetra au set. (déjà là ça plante, avec une erreur illisible de la STD (une histoire de pointeur ou je ne sais quoi) une erreur qui ressemble à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    /usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_tree.h:877:   instantiated from «std::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::insert_unique(const _Val&) [with _Key = Tetra, _Val = Tetra, _KeyOfValue = std::_Identity<Tetra>, _Compare = std::less<Tetra>, _Alloc = std::allocator<Tetra>]»
    /usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_set.h:315:   instantiated from «std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, _Alloc>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = Tetra, _Compare = std::less<Tetra>, _Alloc = std::allocator<Tetra>]»
    Alors voici les précisions que je demande :
    • Comment utiliser pair pour savoir si l'insertion dans le set s'est faite, ou si c t un doublon ?
    • Comment insérer un Tetra dans le set
      car solution.insert(tetra); ne fonctionne pas des masses, j'ai essayer diverses solution, avec des *, des &, avec rien du tout etc ... bref je pige pas cette fonction, d'autant plus que dans tout les exemples que j'ai lu ça se faisait le plus simplement du monde avec justement ce que j'ai écrit...
    • Comment fonctionne le tri automatique des set, parceque j'ai l'impression que mon triTetraCroissant pose aussi des problème

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut Pour comparer les choses, il faut savoir comment les comparer...
    Salut,

    Pour pouvoir trier des objets, la première chose qu'il faut, c'est... un moyen de les comparer...

    Tu dois donc, soit créer un prédicat du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    bool Tetra::less( Tetra& b) const
    {
        //ce qu'il faut pour déterminer si *this est plus petit que b
       return resultat;
    }
    soit envisager la surcharge des operateurs de comparaison (< et >, mais peut etre aussi ==, !=, voire <= et >=) sous une forme du genre de
    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
     
    bool Tetra::operator >(Tetra& a, Tetra &b) const
    {
        //ce qu'il faut pour déterminer que a>b
        return resultat;
    }
    bool Tetra::operator <(Tetra& a, Tetra &b) const
    {
        //ce qu'il faut pour déterminer que a<b
        return resultat;
    }
    bool Tetra::operator ==(Tetra& a, Tetra &b) const
    {
        //ce qu'il faut pour déterminer que a==b
        return resultat;
    }
    bool Tetra::operator !=(Tetra& a, Tetra &b) const
    {
        //ce qu'il faut pour déterminer que a!=b
        return resultat;
    }
    Le tout, évidemment, en prenant en compte que tu dois pouvoir avoir une quantité de Tetra suffisante pour ton projet...:

    Tu pourrais, ainsi, décider de coder (less) sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    bool Tetra::less( Tetra& b) const
    {
       return (this->type<b.type);
    }
    mais tu ne pourrais donc jamais avoir qu'un seul Tetra de chaque type (donc, 5 Tetra simultanés au maximum)...
    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 confirmé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 134
    Par défaut
    hum hum ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct triTetraCroissant
    { 
    	bool operator ()( Tetra & t1,  Tetra & t2) const 
    	{ 
    		return t1.getcase(0) < t2.getcase(0);
    	}
    };
    Ce bout de code là ne code-t-il pas une fonction
    triTetraCroissant( Tetra & t1, Tetra & t2)
    qui compare 2 élément

    et si je construit mon set ainsi
    set<Tetra, triTetraCroissant> solution;
    ça devrait suffir non ?

    Je dois avouer que les surcharge d'opérateur me trouble...
    d'une fois sur l'autre je ne sais jamais si c des friend, des public, des "en-dehors de la classe" etc... bref si je décide de faire ce qui me parait le plus simple et clair pour moi : la surcharge des opérateurs existant (plutot que de recréer je ne sais quoi avec des struct)
    alors pour le tri du set je n'ai besoin que de surcharger < non ? (je veux qu'il les tri par ordre croissant)

    si oui, alors ma classe tetra deviens:
    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
    28
    class Tetra {
    public:
    	Tetra(ui s1, ui s2, ui s3, ui s4);
     
     
    	ui operator[] (ui ref) {return cases[ref];};
    	bool operator< (Tetra & t) const;
     
     
    	void set(ui s1, ui s2, ui s3, ui s4);
     
    	int getType()    { return type;}
    	ui getcase(ui i) { return cases[i];}
    	ui getX(ui i)    { return xcases[i];}
    	ui getY(ui i)    { return ycases[i];}
     
     
    private:
    	int findType();
     
    	ui cases[4];  // par ordre croissant
    	ui xcases[4]; // les coord x des cases
    	ui ycases[4]; // les coord y des cases
    	int type; // 5 differents (cf define)
     
    };
     
    ostream & operator<< (ostream &  , Tetra &); // affichage en console
    et dans le cpp associé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool Tetra::operator <(Tetra& t) const
    {
        return cases[0] < t.getcase(0);
    }

    Seulement comment dire dans le set qu'on compare avec <
    car j'ai essayer plusieur solution mais ça ne marche pas
    set<Tetra, opertor<> solution;
    set<Tetra, less> solution
    set<Tetra, <> solution
    ...

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Ça serait bien d'ajouter les const pour les références.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 134
    Par défaut
    bah quand je les met pas ça compile

    mais quand je les met :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tetra.cpp:135: erreur: passing «const Tetra» as «this» argument of «unsigned int Tetra::getcase(unsigned int)» discards qualifiers
    donc bon.

    mais a priori sans les const ça marche. Pour l'instant j'essaie surtout de faire un code qui marche , on verra aprés pour du code propre etc...

    personne n'a d'idée du pourquoi du comment de mes erreurs quand je veux insérer un Tetra dans le set solution ??

    Voici mon main.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    main (int argc, char* argv)
    {
    	cout << "salut\n";
    	Solution sol;
    	cout << "size = " << sol.getSize() << endl;
    	Tetra t1(0,1,2,3);
    	sol.addTetra(t1);
     
    	cout << "size = " << sol.getSize() << endl; 
    }
    Ma classe Tetra est visible quelques poste plus haut
    et voici ma méthode addTetra:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int Solution::addTetra(Tetra tetra)
    {
    	solution.insert(tetra);
    }
    et quand je compile ça plante avec l'erreur illisible de la STL
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_function.h: In member function «bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Tetra]»:
    /usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_tree.h:877:   instantiated from «std::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::insert_unique(const _Val&) [with _Key = Tetra, _Val = Tetra, _KeyOfValue = std::_Identity<Tetra>, _Compare = std::less<Tetra>, _Alloc = std::allocator<Tetra>]»
    /usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_set.h:315:   instantiated from «std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, _Alloc>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = Tetra, _Compare = std::less<Tetra>, _Alloc = std::allocator<Tetra>]»
    solution.cpp:27:   instantiated from here
    /usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../include/c++/4.0.3/bits/stl_function.h:227: erreur: no match for «operator<» in «__x < __y»
    tetra.h:25: note: candidats sont: bool Tetra::operator<(Tetra&) const

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Citation Envoyé par Ikit
    bah quand je les met pas ça compile

    mais quand je les met :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tetra.cpp:135: erreur: passing «const Tetra» as «this» argument of «unsigned int Tetra::getcase(unsigned int)» discards qualifiers
    donc bon.
    Normal tu as oublié de spécifier que la fonction membre getcase fonctionnait avec un objet constant.

    À part ça ton operator[] est pas bon non plus, mais bon ça a rien à voir.

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

Discussions similaires

  1. Utilisation des Settings
    Par Rogue 9 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 10/06/2008, 11h42
  2. Utilisation des settings
    Par Poulain dans le forum Windows Forms
    Réponses: 6
    Dernier message: 24/04/2008, 14h03
  3. Réponses: 1
    Dernier message: 28/04/2007, 00h07
  4. Réponses: 2
    Dernier message: 31/10/2006, 16h29
  5. Utilisation des sets
    Par Original Prankster dans le forum SL & STL
    Réponses: 6
    Dernier message: 08/02/2006, 21h28

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