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++

  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.

  7. #7
    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
    ok merci loufoque


    ... mais ça m'aide pas pour mes set moi





    [edit]
    Alors là... je viens de recompiler
    et ça marche
    Vous qui avez compris ce qui s'est passé, vous pourriez m'expliquer ?

    Il semblerait que les const de loufoque ait résolu le problème.

  8. #8
    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
    Bon sinon je rappel que mes première questions sur les set sont toujours d'actualités...
    • Comment utiliser pair pour savoir si l'insertion dans le set s'est faite, ou si c t un doublon ?

    J'ai vu quelque part cette méthode là... mais ça ne marche pas (pas d'erreur, mais il me renvoie toujour la même réponse, même quand je force les erreurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int Solution::addTetra(Tetra tetra)
    {
    	pair <Tetra *, bool> p;
    	solution.insert(t_bis);
    	if (p.second) return SOLUTION_INVALIDE;
    	return SOLUTION_PARTIELLE;
     
    }

  9. #9
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Il faudrait peut-être affecter p, non ?
    Rien de tel que la doc pour comprendre ce qui manque à ton code =>
    http://dinkumware.com/manuals/?manua...ml#set::insert
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  10. #10
    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
    effectivement ça serait mieux.

    merci pour le lien, ça m'a aidé, donc maintenant que ça marche,
    Pour infoi voici maintenant le code de cette fonction
    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
    int Solution::addTetra(Tetra tetra)
    {
    	Tetra * t_bis = new Tetra(tetra);
     
    	cout << &t_bis;
    	if (tetra_par_type[ tetra.getType() -1] > 2)
    	{
    		return SOLUTION_INVALIDE;
    	}
    	pair <std::set<Tetra>::iterator, bool> p;
     
    	p = solution.insert(*t_bis);
    	if (!p.second) return SOLUTION_INVALIDE;
     
    	if (solution.size() == 10) return SOLUTION_COMPLETE;
     
    	return SOLUTION_PARTIELLE;
     
    }

    Comme vous l'avez peut etre remarqué j'ai mis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tetra * t_bis = new Tetra(tetra);
    Parcequ'en fait, insert prend la référence de l'objet pour l'insérer dans le set.
    Or comme ma boucle ne travail qu'avec un seul objet Tetra, il l'insère la première fois dans la solution, mais aprés il ne le fait plus (normal)
    J'ai donc essayer de créer avant chaque insertion un nouvel objet Tetra

    Tetra * t_bis = new Tetra(tetra);
    cout << &t_bis;

    Seulement ça ne change rien, et dans ma boucle,
    Le cout << &t_bis; renvoie toujour la même adresse, ce qui fait qu'encore une fois, mon set n'insère pas les nouveaux objets

    Vous avez une idée pour régler ce problème ?

  11. #11
    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
    Je ne suis pas certain que ta fonction de comparaison fasse ce que tu veux. Telle qu'elle est définie, pour peu que deux tetra aient la première case identique, ils seront considérés entièrement identiques, et un seul sera inséré.
    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.

  12. #12
    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
    aucuns Tetras ne peux avoir de cases identiques, c'est la boucle qui s'en assure (car les tetras sont disposé sur un damier, et si les cases sont déjà occupé par un tetras, la boucle ne prend pas en compte ces cases pour construire d'autre Tetras.


    Ma fonction sort est là pour trier les objets tetras dans la solution. et comme les cases des Tetras sont elles aussi trié par ordre croissant, celà revient pour organiser ma solution qu'à comparer les 2 premières cases de chaques tétras.


    Mais en tout cas, c incroyablement compliqué les set
    J'ai beau m'inspirer de tout les exemples du monde, ça ne fait jamais ce que je souhaite. (là je galère avec des itareurs... Mais j'ai l'impression que comme précédement c'est encore une histoire de const qui pour un constructeur par copie ou par autre chose qui bloque :'( )

  13. #13
    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
    Bon merci à tous pour votre aide, visiblement ça marche
    (Je crois que finalement mes erreurs étaient dû à des const mal placé et des histoire ed pointeurs/référence etc...)


    Encore quelques petites questions ?
    OUIIIIIII


    Alors :
    #1
    J'aimerais comprendre comment le set gère ses insertions.
    Car dans mon programme, il ne prend que la référence de l'objet que je veux insérer, et cet objet est dans une boucle qui le modifie en permanence, hors au final tout marche..., Comment il fait pour savoir que 2 élément sont différent du coup (vu que ma boucle modifie un objet qu'il a insérer non ?) !

    #2
    En lisant votre faq ici : sur les const
    je vois que la méthode existe en 2 version, une avec et une sans le const. Est-ce que je dois le faire aussi pour mes méthodes ? où la version avec les const suffit ?

    #3
    Voici ma classe tetra.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
    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
    class Tetra {
    public:
    	Tetra(const ui s1, const ui s2,const  ui s3,const  ui s4);
    	Tetra(const Tetra & );
    	//Tetra operator= ( const Tetra & );
     
    	ui operator[] (ui ref) const {return cases[ref];};
    	bool operator<  (const Tetra& t) const;
     
    	void set(const ui s1, const ui s2, const ui s3, const ui s4);
     
    	int getType()  const         { return type;}
    	ui getcase(const ui i) const { return cases[i];}
    	ui getX(const ui i) const    { return xcases[i];}
    	ui getY(const ui i) const    { 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 Sort
    { 
       bool operator ()(const Tetra& t1,const Tetra& t2) const 
       { 
          return t1.getcase(0) < t2.getcase(0);
       } 
    };
     
     
    bool operator== (const Tetra& t1, const Tetra& t2);
    bool operator!= (const Tetra& t1, const Tetra& t2);
    ostream & operator<< (ostream &  , const Tetra &);
    J'ai comme l'impression que c'est du grand n'importe quoi ... Surtout au niveau des opérateurs surcharger. Mais si je met l'opérateur operator< avec les 3 autres en dehors de la classe ça ne compile pas, et si je met les operator == et != avec le <, ça ne marche pas non plus.
    Je ne comprend pas ya une règle pour ça je suppose ?

    Au passage, je n'ai pas réussi à compiler en décommantant le constructeur
    Tetra operator= ( const Tetra & );

    défini ainsi dans le cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Tetra::Tetra operator= ( const Tetra & t)
    {
    	//set(t.getcase(0), t.getcase(1), t.getcase(2), t.getcase(3));
    }
    j'obtient l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    tetra.cpp:22: erreur: «Tetra operator=(const Tetra&)» must be a nonstatic member function
    tetra.cpp:22: erreur: «Tetra operator=(const Tetra&)» must take exactly two arguments
    Comment ça nonstatic ? elle est static là ma fonction ????
    depuis quand ce constructeur doit prendre 2 arguments ?

  14. #14
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int Solution::addTetra(Tetra tetra)
    {
    	Tetra * t_bis = new Tetra(tetra);
    Trop de copies et allocations inutiles (sans parler d'une fuite mémoire) en un temps record.

    C'est quand même pas compliqué...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int Solution::addTetra(const Tetra& tetra)
    {
    	if (tetra_par_type[ tetra.getType() -1] > 2)
    	{
    		return SOLUTION_INVALIDE;
    	}
    	std::pair <std::set<Tetra>::iterator, bool> p = solution.insert(tetra);
    	if (!p.second) return SOLUTION_INVALIDE;
     
    	if (solution.size() == 10) return SOLUTION_COMPLETE;
     
    	return SOLUTION_PARTIELLE;
     
    }
    Seulement ça ne change rien, et dans ma boucle,
    Le cout << &t_bis; renvoie toujour la même adresse
    Normal, tu demandes d'afficher l'adresse d'une variable qui est sur la pile.

    #1
    J'aimerais comprendre comment le set gère ses insertions.
    Car dans mon programme, il ne prend que la référence de l'objet que je veux insérer, et cet objet est dans une boucle qui le modifie en permanence, hors au final tout marche..., Comment il fait pour savoir que 2 élément sont différent du coup (vu que ma boucle modifie un objet qu'il a insérer non ?) !
    Un conteneur, comme son nom l'indique, contient les objets. Par conséquent, il fait une copie de ce que tu lui demandes d'insérer.
    D'ailleurs techniquement il ne pourrait pas insérer un truc qui est sur la pile directement, il a besoin de l'allouer sur une mémoire libre non sujette à la portée. La copie est indispensable.

    #2
    En lisant votre faq ici : sur les const
    je vois que la méthode existe en 2 version, une avec et une sans le const. Est-ce que je dois le faire aussi pour mes méthodes ? où la version avec les const suffit ?
    Tu peux fournir deux définitions si cela a du sens, oui.
    Mais dans ton cas, à part pour operator[] qui est de toutes manières mal écrit, ça ne sert à rien.

    Tetra operator= ( const Tetra & );
    Ça devrait pas retourner une référence plutôt ?

  15. #15
    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
    Lol vous allez me trouver lourd mais bon.
    D'abord merci loufoque pour tes précisions.


    Ensuite,
    Il se passe des choses étranges.


    J'ai une boucle qui travail avec un objet tetra

    dans un set, j'insére les tétras trouvé. Ainsi, comme le set est sans doublons, ça m'évite de travailler 2 sur le même, et si c la première fois que je vois, je le sais grace a la réponse de l'insertion.

    voici le passage de la boucle ou tout ça se fait :
    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
    				Tetra tt(tetra[0], tetra[1], tetra[2], tetra[3]);
     
    				// On verifie qu'on n'a pas deja teste ce tetra 
    				cout << profondeur << " : ";
    				bool_test = addTetraDejaVu(tetra_deja_vu, tt);
     
    				// ICI C JUSTE DE L'AFFICHAGE, C PAS IMPORTANT =======
    				if ( !bool_test)
    				{
    					for (std::set<Tetra>::iterator it = tetra_deja_vu.begin(); it != tetra_deja_vu.end(); it++)
    					{
    						cout << " > " << *it << endl;
    					}
    					continue;
    				}

    voici à quoi ressemble ma fonction addTetraDejaVu(tetra_deja_vu, tt);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    bool DamierTetramino::addTetraDejaVu(set<Tetra> & leset, Tetra tetra)
    {
    	cout << "ADD TETRA SET " << leset.size() << " - " << tetra;
    	pair <std::set<Tetra>::iterator, bool> p;
     
    	p = leset.insert(tetra);
    	cout << " **" << p.second << "**" << endl;
     
    	if (!p.second) return false;
    	return true;
    }
    Donc normalement, le set tetra_deja_vu contient tout les tetra que j'ai déjà croisé précédemment, et si ce n'est pas le cas, le set l'ajoute et m'indique qu'il a réussi à l'insérer...

    Or il arrive bien à m'insérer le premier tetra qu'il rencontre, mais pas les suivant. et pourtant ils sont bien différents de celui dans le set :s
    Voici ce que m'affiche l'exécution du programme
    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
     
    3 : ADD TETRA SET 1 - Tetra [4 - 5 - 12 - 13  | 2]  **0**
     > Tetra [4 - 5 - 12 - 20  | 1]
     
    3 : ADD TETRA SET 1 - Tetra [4 - 5 - 11 - 12  | 4]  **0**
     > Tetra [4 - 5 - 12 - 20  | 1]
     
    3 : ADD TETRA SET 1 - Tetra [4 - 5 - 12 - 13  | 2]  **0**
     > Tetra [4 - 5 - 12 - 20  | 1]
     
    3 : ADD TETRA SET 1 - Tetra [4 - 5 - 6 - 12  | 1]  **0**
     > Tetra [4 - 5 - 12 - 20  | 1]
     
     
    ....
    Les lignes commençant par
    sont affiché par la fonction addTetraDejaVu. Le 3 indique qu'on est à une profondeur 3 de l'algo (fonction récursive s'appelant pour la 3èm fois)
    Le chiffre qui suit (ici 1)à indique la taille du set., et tout ce qui suit donne les information du Tetra qu'on tente d'insérer dans le set tetra_deja_vu
    Au bout de la ligne le " **0**" indique le résultat de l'insertion (donc là ça foire à tout les coup)

    La ligne juste en dessous (commençant par " > Tetra")
    est un cout << du set set tetra_deja_vu

    Je ne comprend vraiment pas pourquoi ça ne marche, Les objets Tetras sont pourtant bien différents ! ! !
    Et j'ai surchargé pour être sûr les opérateurs == et != des objets tetras de façon à ce qu'il les compare correctement, mais en mettant des cout dans ces opérateurs, je me suis aperçut qu'il ne les utilisait même pas ! !
    Donc comment le set s'y prend pour vérifier qu'il ne s'agit pas de doublons. car là j'ai du mal à comprendre.
    Surtout que la ya pas de doublons et pourtant l'insertion échoue. Une idée sur la cause ?

  16. #16
    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
    Tu devrais même à avoir à définir le constructeur de copie et l'opérateur d'affectation, ceux par défaut devraient très bien aller.

    Enfin là en regardant vite fait apparemment ton problème c'est qu'il te dit pas qu'un élément est déjà inséré alors que c'est le cas. Donc c'est un problème de comparaison.

    À part ça rien que dans le code que tu viens de montrer tu fais encore des copies inutiles, malgré ce que je t'ai dit précédemment...

  17. #17
    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
    À part ça rien que dans le code que tu viens de montrer tu fais encore des copies inutiles, malgré ce que je t'ai dit précédemment...
    Je pense que tu fait allusion à mon passage par copie du Tetra dans la fonction addTetraDejaVu?
    Si oui est-ce mieux ainsi ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    bool DamierTetramino::addTetraDejaVu(set<Tetra> & leset, Tetra &tetra)
    {
    	//cout << "ADD TETRA SET " << leset.size() << " - " << *tetra;
    	pair <std::set<Tetra>::iterator, bool> p;
     
    	p = leset.insert(tetra);
    	cout << p.second << endl;
     
    	if (!p.second) return false;
    	return true;
    }
    J'ai aussi changer mon Tetra tt(...) qui été dans la boucle en tt.set(...), avec l'instantiation Tetra tt; en début de fction
    Sinon à part ça, je ne vois pas d'autres copies inutiles


    Je viens de tester en commentant les construteurs de copie et d'affectation, mais ça n'a rien résolu... aïe aïe aïe !
    Mais en tout cas, je procède de la bonne manière pour insérer dans le set là ?
    donc ça viens des objets Tetra ?


    [EDIT]
    Donc il se pourrait que ça vienne de la surcharge de l'opérateur < que j'ai fait de mes Tetra...
    Car quand je commante ce que j'ai fait, j'obtient une erreur de la STD (les erreurs illisibles du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     /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]»:
    Le truc, c'est qu'à aucun moment je lui ait dit pour comparer ou trier dans le sort d'utiliser less, donc il a fait ça tout seul ... je ne vois pas en quoi ça lui permet de détecter les doublons m'enfin bon,
    En tout cas, voici comment j'avais défini less pour mes Tetra,
    Dans tetra.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     	bool operator<  (const Tetra& t) const;
    dans le cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool Tetra::operator< (const Tetra& t) const
    {
    	return cases[0] < t.getcase(0);
    }
    Et bien sur comme tout les tetras avaient la même case 0 par construction, il comprennais pas.
    Donc j'ai recodé ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bool Tetra::operator< (const Tetra& t) const
    {
    	for (int i=0; i<4; i++)
    	{
    		if (cases[i] != t.getcase(i))
    			return cases[i] < t.getcase(i);
    	}
    	return false;
    }
    Et maintenant ça marche nikel

    Grand merci pour votre patience, et votre compétence

+ 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