Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1624 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Problème tri d'une liste objet (STL)

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème tri d'une liste objet (STL)

n°624522
tomsawyer1​21
Posté le 29-01-2004 à 06:48:21  profilanswer
 

Bonjour, j'aimerais savoir comment on fait pour surdéfinir un foncteur de tri de liste d'objet. C'est objet sont des pointeurs sur une structure et la liste doit étre trier de facin croissante sur un élément de cette structure ! Si qqu'un savait m'aider c'est sympa. Merci
 
///Voici la structure :
 
struct Location
{
    string type;
    int prop;
    LiPtReserv* PtR;
};
 
/// Je déclare un type LiPtLoc, une liste de pointeur sur la structure.
 
typedef list <Location*> LiPtLoc;
 
--> J'aimerai bien que la fonction sort des list, puissant tirer la liste de manière croissante sur la variable type ? Voila mon problème.
 
Merci
 
Si vous voulez plus d'info demander les merci ++
 
Tom Sawyer

mood
Publicité
Posté le 29-01-2004 à 06:48:21  profilanswer
 

n°624561
SoWhatIn22
Posté le 29-01-2004 à 09:22:40  profilanswer
 

on peut faire qqchose comme cela.
Bon, j'ai pas des pointeurs, mais tu peux t'en inspirer.
On doit pouvoir faire mieux pour afficher avec des std::copy et des std::ostream_iterator, mais je ne maitrise pas bien cela.
 

Code :
  1. #include <iostream>
  2. #include <string>
  3. #include <list>
  4. using namespace std;
  5. struct LOCATION
  6. {
  7. string type;
  8. int prop;
  9. void * reserved;
  10. void init(const string & t, int p)
  11.  {
  12.   type=t;
  13.   prop=p;
  14.  }
  15. void display()
  16.  {
  17.   cout << "item: type=\""<<type<<"\", prop="<<prop<<std::endl;
  18.  }
  19. };
  20. struct lt_locs
  21. {
  22. bool operator() (LOCATION loc1, LOCATION loc2 ) const
  23.  {
  24.   return (loc1.prop<loc2.prop);
  25.  }
  26. };
  27. void display( list<LOCATION> & locs )
  28. {
  29. list<LOCATION>::iterator it;
  30. for(it=locs.begin();it!=locs.end();++it)
  31. {
  32.  (*it).display();
  33. }
  34. }
  35. int main(int argc, char *argv[])
  36. {
  37. LOCATION loc1,loc2,loc3;
  38. loc1.init("maison",1);
  39. loc2.init("appart",2);
  40. loc3.init("studio",3);
  41. list<LOCATION> loclist;
  42. loclist.push_back(loc2);
  43. loclist.push_back(loc3);
  44. loclist.push_back(loc1);
  45. cout<<"before sorting..."<<endl;
  46. display(loclist);
  47. cout<<endl;
  48. cout<<"after sorting..."<<endl;
  49. loclist.sort(lt_locs());
  50. display(loclist);
  51. return 0;
  52. }


Message édité par SoWhatIn22 le 29-01-2004 à 09:23:11
n°624648
Taz
bisounours-codeur
Posté le 29-01-2004 à 11:09:05  profilanswer
 

    void init(const string & t, int p)
      {
         type=t;
         prop=p;
      }  
 
 
c'est quoi ce foutage de gueule ?
 
 
 
ton membre display, tu le fous en const
ta structure lt_bordel, tu la ranges, tu fais un simple operator< global est on est tranquille

n°624664
SoWhatIn22
Posté le 29-01-2004 à 11:22:52  profilanswer
 

taz a écrit :

    void init(const string & t, int p)
      {
         type=t;
         prop=p;
      }  
 
 
c'est quoi ce foutage de gueule ?
 
 
 
ton membre display, tu le fous en const
ta structure lt_bordel, tu la ranges, tu fais un simple operator< global est on est tranquille


 
> c'est quoi ce foutage de gueule ?
quel foutage de geule? tu aurrais préféré un constructeur, c'est ça? M'en fous, c'est un exemple...
 
>ton membre display, tu le fous en const
cf remarque précédente.
 
> ta structure lt_bordel
c'est lt_locs, pas lt_bordel.
spécifier cette structure a quand même l'avantage de montrer comment on fait avec cette méthode. Maintenant, si tu veux aussi utiliser l'opérateur < , et ben arrête ta crise de mégalo et montre comment on fait au lieu de hurler. Tout le monde n'a pas ton niveau en C++.

n°624681
Taz
bisounours-codeur
Posté le 29-01-2004 à 11:34:21  profilanswer
 

ben donné un exemple pourri, c'est pas rendre service. Quand tu donnes une solution, faut l'expliquer et la critiquer.
 
C'est pas qu'une histoire de niveau : le coup du init et des const, ce sont des erreurs de débutants.

n°624696
SoWhatIn22
Posté le 29-01-2004 à 11:40:05  profilanswer
 

t'as raison, c'est encore mieux de ne rien donner.
 
> Quand tu donnes une solution, faut l'expliquer et la critiquer.
Pas besoin d'utiliser des termes insultants ou rabaissants pour critiquer.

n°624719
Taz
bisounours-codeur
Posté le 29-01-2004 à 11:59:39  profilanswer
 

Code :
  1. #include <iostream>
  2. #include <string>
  3. #include <list>
  4.  
  5. using namespace std;
  6.  
  7. struct Location
  8. {
  9.   enum Type
  10.     {
  11.       maison,
  12.       appartement,
  13.       studio
  14.     };
  15.   Type type;
  16.   int prop; // bof
  17.   // mélanger français et anglias ...
  18.   void * reserved; // c'est quoi?
  19.    
  20.   Location(Type t, int p)
  21.     : type(t),
  22.       prop(p),
  23.       reserved(0)
  24.   {}
  25.   void print(ostream &out) const
  26.   {
  27.     out << "item: type=\"";
  28.     switch(type)
  29.       {
  30.       case maison:
  31. out << "maison"; break;
  32.       case appartement:
  33. out << "appartement"; break;
  34.       case studio:
  35. out << "studio"; break;
  36.       default:
  37. out << "inconnu"; break;
  38.       }
  39.     out << "\",\tprop=" << prop << '\n';
  40.   }
  41. };
  42. inline bool operator<(const Location &lhs, const Location &rhs)
  43. {
  44.   return lhs.prop < rhs.prop;
  45. }
  46.  
  47.  
  48. void display(const list<Location> & locs )
  49. {
  50.   typedef list<Location>::const_iterator const_iterator;
  51.   const const_iterator end(locs.end());
  52.   for(const_iterator it(locs.begin()); it!=end; ++it)
  53.     {
  54.       it->print(cout);
  55.     }
  56.   cout << endl;
  57. }
  58.  
  59. int main(int argc, char *argv[])
  60. {
  61.   list<Location> loclist;
  62.   loclist.push_back( Location(Location::maison, 1) );
  63.   loclist.push_back( Location(Location::studio, 10) );
  64.   loclist.push_back( Location(Location::studio, 4) );
  65.   loclist.push_back( Location(Location::appartement, 2) );
  66.   loclist.push_back( Location(Location::studio, 3) );
  67.   loclist.push_back( Location(Location::studio, 15) );
  68.  
  69.   display(loclist);
  70.   loclist.sort();
  71.   display(loclist);
  72. }

n°625067
tomsawyer1​21
Posté le 29-01-2004 à 16:37:38  profilanswer
 

donc si j'ai bien compris avec ta méthode taz, je n'ai pas besoin de définir une fonction de tri. Cette méthode me semble bonne mais je suis obliger d'avoir un string pour le type alors faut ke j'emploie l'autre !

n°625089
tomsawyer1​21
Posté le 29-01-2004 à 16:49:59  profilanswer
 

SoWhatIn22 a écrit :

on peut faire qqchose comme cela.
Bon, j'ai pas des pointeurs, mais tu peux t'en inspirer.
On doit pouvoir faire mieux pour afficher avec des std::copy et des std::ostream_iterator, mais je ne maitrise pas bien cela.
 

Code :
  1. #include <iostream>
  2. #include <string>
  3. #include <list>
  4. using namespace std;
  5. struct LOCATION
  6. {
  7. string type;
  8. int prop;
  9. void * reserved;
  10. void init(const string & t, int p)
  11.  {
  12.   type=t;
  13.   prop=p;
  14.  }
  15. void display()
  16.  {
  17.   cout << "item: type=\""<<type<<"\", prop="<<prop<<std::endl;
  18.  }
  19. };
  20. struct lt_locs
  21. {
  22. bool operator() (LOCATION loc1, LOCATION loc2 ) const
  23.  {
  24.   return (loc1.prop<loc2.prop);
  25.  }
  26. };
  27. void display( list<LOCATION> & locs )
  28. {
  29. list<LOCATION>::iterator it;
  30. for(it=locs.begin();it!=locs.end();++it)
  31. {
  32.  (*it).display();
  33. }
  34. }
  35. int main(int argc, char *argv[])
  36. {
  37. LOCATION loc1,loc2,loc3;
  38. loc1.init("maison",1);
  39. loc2.init("appart",2);
  40. loc3.init("studio",3);
  41. list<LOCATION> loclist;
  42. loclist.push_back(loc2);
  43. loclist.push_back(loc3);
  44. loclist.push_back(loc1);
  45. cout<<"before sorting..."<<endl;
  46. display(loclist);
  47. cout<<endl;
  48. cout<<"after sorting..."<<endl;
  49. loclist.sort(lt_locs());
  50. display(loclist);
  51. return 0;
  52. }




 
 
 
J'ai essaye en me bassant sur ton exemple et il me met l'erreur
 
void __thiscall std::list<struct Location *,class std::allocator<struct Location *> >::sort(struct std::greater<struct Location *> )' : cannot convert parameter 1 from 'struct tri' to 'struct std::greater<struct Location *>
 
voici mon foncteur:
 

Code :
  1. struct tri{
  2. int operator ()(struct Location* L1, struct Location* L2) const
  3. {
  4.  return(L1->type<L2->type);
  5. };
  6. };

n°625093
Kristoph
Posté le 29-01-2004 à 16:57:08  profilanswer
 

tomsawyer121 a écrit :

donc si j'ai bien compris avec ta méthode taz, je n'ai pas besoin de définir une fonction de tri. Cette méthode me semble bonne mais je suis obliger d'avoir un string pour le type alors faut ke j'emploie l'autre !


 
Tu n'as pas bien compris sa méthode donc.
 
Sinon, pour ton problème de compilation : quel compilateur C++ utilises-tu et quelle STL dans l'hypothèse ou tu l'aurais changé ?

mood
Publicité
Posté le 29-01-2004 à 16:57:08  profilanswer
 

n°625098
tomsawyer1​21
Posté le 29-01-2004 à 17:00:10  profilanswer
 

Kristoph a écrit :


 
Tu n'as pas bien compris sa méthode donc.
 
Sinon, pour ton problème de compilation : quel compilateur C++ utilises-tu et quelle STL dans l'hypothèse ou tu l'aurais changé ?


 
J'utilise Visual C++ 6.0 de Microsoft et la version de la STL je c pas mais j'ai rien changé

n°625186
blackgodde​ss
vive le troll !
Posté le 29-01-2004 à 18:08:23  profilanswer
 

bin la stl de vc++6 est pas super conforme a la stl original ...


---------------
-( BlackGoddess )-
n°670695
EmmaB_bj
°Bloub°
Posté le 11-03-2004 à 13:39:50  profilanswer
 

Bonjour,
 
J'ai trouvé la solution...
J'avais le même problème ( je suis aussi ss VC++ 6)et je suis tombé sur ce forum.
Bon peut être as tu fait autrement finalement vu que ton mesg date de Janvier...Mais si à tt hasard, qqu'un a le même problème...
 
Comme je l'ai résolu j'en fais profiter :
 
Il faut encapsuler la structure dans un objet auquel tu dois définir les opérateurs >, <, ==,!=, =, constructeur par copie:
Ainsi dans ton cas :
 
struct Location
{
   string type;
   int prop;
   LiPtReserv* PtR;
};
 
Class CapsuleLocation
{
public:
Location* VLocation;
 
CapsuleLocation(); //constructeur
CapsuleLocation(CapsuleLocation &_copy);
CapsuleLocation(Location* _val); // pour créer l'objet d'encapsulation
virtual ~CapsuleLocation();
bool operator>(const CapsuleLocation autre);
bool operator<(const CapsuleLocation autre);
bool operator==(const CapsuleLocation autre);
bool operator!=(const CapsuleLocation autre);
CapsuleLocation& operator=(const CapsuleLocation autre);
}
 
// Tu définis tes opérateur en fonction de la valeur que tu veux comparer :
// ainsi par exemple( je montre que pour celle-ci....
// après ça en découle.
 
bool CapsuleLocation::operator> ( const CapsuleLocation autre)
{
return (strcmp(VLocation->type,autre.VLocation->type) > 0 );
 
}
 
// Donc pareil pour les autres opérateur.
 
//Après tu peut déclarer:
typedef list <CapsuleLocation> LiPtLoc;
 
//Et ensuite:
LiPtLoc ListeLocations;
...
//[rentrer des valeurs]
...
//Cet appel ne devrait pas générer d'erreur.
//En tout cas pour moi sous VC++ 6, j'en ai pas!
ListeLocation.sort();
 
//sort utilise les opérateurs de comparaison de l'objet.
//suivant l'implémentation de la STL..c'est LessThan( souvent c plutôt ça) ou GreaterThan( pour certain sort dans VC++6, notamment)...Le plus sûr est de définir tous les opérateurs de comparaison pour d'autre opération( find par exemple)
//Bon après, il faut faire gaffe aux fuites mémoires.
 
//Ne pas détruire la structure dans le destructeur de CapsuleLocation! En effet, lors d'une copy, si on a créé un objet [Obj] local à la fonction pour faire un [ListLocation.push-back(Obj)], celui-ci est recopié dans ListLocation et va être détruit à la fin... Donc pas de libératio n mémoire dans le destructeur de CapsuleLocation !
 
Il faut donc gérer la destruction de Location* autre part.
Mais bon, comme tu mets des pointeurs d'objets dans ta liste, je pense que tu as dû y penser...
 
Voilà Voili!
 
 
 
-----------------
 
 

n°670698
Taz
bisounours-codeur
Posté le 11-03-2004 à 13:43:38  profilanswer
 

ouais, ça t'oblige a des tas de bêtises pour rien
 
bool operator>(const CapsuleLocation autre);
bool operator<(const CapsuleLocation autre);
bool operator==(const CapsuleLocation autre);
bool operator!=(const CapsuleLocation autre);
 
 
surtout que tout ça c'est pas des signatures valides

n°670786
EmmaB_bj
°Bloub°
Posté le 11-03-2004 à 15:15:20  profilanswer
 

Oups ? Ah pkoi ce n'est pas des signautre valides?  
Je sais pas trop pour ma part, mais ça compile sous VC+6 ?
Si je me trompe, dites... ça m'évitera des surprise au build...


---------------
-----------------------------------------------
n°670788
Taz
bisounours-codeur
Posté le 11-03-2004 à 15:18:27  profilanswer
 

mande des références et des const.
 
etce genre d'opération n'est pas une opération interne, il vaut mieux les définir en dehors de la classe

n°670791
EmmaB_bj
°Bloub°
Posté le 11-03-2004 à 15:25:09  profilanswer
 

Mais dans :
 bool operator>(const CapsuleLocation autre);  
 
autre : Ce n'est pas une reference...C'est pas valeur.
 
Operation interne ?  
Mais si on utilise liste.sort() sans argument, alors la methode utilise l'opérateur de l'objet.... D'où la nécessité de le déclarer comme ça.
 
Sinon ya erreur de compil sous VC++6
Il dit qu'il n'existe pas d'opérateur défini à l'objet permettant de comparer.
 


---------------
-----------------------------------------------
n°670793
blackgodde​ss
vive le troll !
Posté le 11-03-2004 à 15:26:23  profilanswer
 

bool operator>(const CapsuleLocation autre);
 
=> utilise plutot une référence pour éviter la copie de l'objet (autre), pour de gros objets ca fera gagner des ressources mémoires (un seul objet au lieu de deux) et CPU (pas de temps passé a copier puis détruire un objet).
 
=> il me semble que d'apres la norme, les opérateurs de comparaison doivent retourner des int (à confirmer)
 
tu aurais donc une déclaration qui ressemble a ca :
int operator>(const CapsuleLocation & autre);


---------------
-( BlackGoddess )-
n°670799
Taz
bisounours-codeur
Posté le 11-03-2004 à 15:32:11  profilanswer
 

le const bordel !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
et bool c'est très bien
int ct quand bool existait pas
 
:o

n°670800
blackgodde​ss
vive le troll !
Posté le 11-03-2004 à 15:32:51  profilanswer
 

bool operator>(const CapsuleLocation & autre) const;
donc :o


---------------
-( BlackGoddess )-
n°670802
EmmaB_bj
°Bloub°
Posté le 11-03-2004 à 15:34:10  profilanswer
 

Hum...
Etant donné que CapsuleLocation n'est qu'une capsule de Location( un pointeur), en espace memoire, ça fait pas des masses vu que c'est la valeur du pointeur.
Aussi je voyais pas trop le truc de mettre une reference, mais ok.
 
Pour ma part, il me semble plutôt que c'est bool pour les opérateurs... Et puis je trouve ça plus clair...
De toute façon, ya compatibilité bool<->int : true(1), false(0)...non?
En tous cas ma compil passe et j'ai pas le truc comme quoi list<> n'arrive pas à trouver l'opérateur.
 
...Et ça sort() !
 
 
 


---------------
-----------------------------------------------
n°670806
EmmaB_bj
°Bloub°
Posté le 11-03-2004 à 15:35:48  profilanswer
 

Ah oui! c plus joli de mettre const à la fin ! ;-)


---------------
-----------------------------------------------
n°670807
Taz
bisounours-codeur
Posté le 11-03-2004 à 15:36:14  profilanswer
 

ça me parait plus simple d'avoir une STL et un compilateur correct. a+

n°670808
blackgodde​ss
vive le troll !
Posté le 11-03-2004 à 15:37:49  profilanswer
 

bin mettre des références pour ca c'est prendre une bonne habitude de coding ... puis pense a l'eventuelle maintenance aussi : si tu décide de 'templatiser' ton code, ou de rajouter des données dans ton objet bin tu auras a tout changer les déclarations de paramètres pour les mettre en références, ce serait bête ...


---------------
-( BlackGoddess )-
n°670821
EmmaB_bj
°Bloub°
Posté le 11-03-2004 à 15:48:20  profilanswer
 

A priori, il faut voir aussi l'utilité de l'objet.
Si on crée une capsule...c pour juste encapsuler un autre truc pointé. Si on rajoute, c plutôt dans l'objet pointé.
Sinon c'est plus une "capsule" !
 
-----
 
Pour le truc des références, c'est vrai c plus joli. Je reconnais.  
 
Hum...Mais si j'ai donné ici mon idée...c pour partager l'essence de l'idée ...et non la forme en détail.  
 
[Attention, je ne dis pas que coder propre c pas bien...Mais je pense qu'ici ce n'était pas le fond du problème.]
 
 
----
 
Taz  : C vrai que j'aimerai un autre compilo avec une vraie STL...mais qd le client te demande VC6++ et pas autre chose...Car envt Windows, OPC,COM/DCOM,S2K... Et bien faut faire avec!


---------------
-----------------------------------------------
mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Problème tri d'une liste objet (STL)

 

Sujets relatifs
[HTML] probleme de position ...PROBLEME AFFICHAGE D IP
probleme pour parser un format notation scientifique (ex : e-179) JAVA[PHP] Problème de cookie [création inside]
[HTML] - Problème d'actualisation de mon site ?héritage ou déclaration d'objet ?
[VB] Problème avec la lecture d'un fichierSTL : gestion des exception. appel explicite?
[CSS] Problème d'impression tableaugetline, problème de template ??
Plus de sujets relatifs à : Problème tri d'une liste objet (STL)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR