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

Problème tri d'une liste objet (STL) - C++ - Programmation

Marsh Posté le 29-01-2004 à 06:48:21    

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

Reply

Marsh Posté le 29-01-2004 à 06:48:21   

Reply

Marsh Posté le 29-01-2004 à 09:22:40    

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
Reply

Marsh Posté le 29-01-2004 à 11:09:05    

    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

Reply

Marsh Posté le 29-01-2004 à 11:22:52    

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

Reply

Marsh Posté le 29-01-2004 à 11:34:21    

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.

Reply

Marsh Posté le 29-01-2004 à 11:40:05    

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.

Reply

Marsh Posté le 29-01-2004 à 11:59:39    

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. }

Reply

Marsh Posté le 29-01-2004 à 16:37:38    

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 !

Reply

Marsh Posté le 29-01-2004 à 16:49:59    

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. };

Reply

Marsh Posté le 29-01-2004 à 16:57:08    

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é ?

Reply

Marsh Posté le 29-01-2004 à 16:57:08   

Reply

Marsh Posté le 29-01-2004 à 17:00:10    

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é

Reply

Marsh Posté le 29-01-2004 à 18:08:23    

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


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 11-03-2004 à 13:39:50    

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

Reply

Marsh Posté le 11-03-2004 à 13:43:38    

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

Reply

Marsh Posté le 11-03-2004 à 15:15:20    

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


---------------
-----------------------------------------------
Reply

Marsh Posté le 11-03-2004 à 15:18:27    

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

Reply

Marsh Posté le 11-03-2004 à 15:25:09    

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.
 


---------------
-----------------------------------------------
Reply

Marsh Posté le 11-03-2004 à 15:26:23    

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 )-
Reply

Marsh Posté le 11-03-2004 à 15:32:11    

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

Reply

Marsh Posté le 11-03-2004 à 15:32:51    

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


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 11-03-2004 à 15:34:10    

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() !
 
 
 


---------------
-----------------------------------------------
Reply

Marsh Posté le 11-03-2004 à 15:35:48    

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


---------------
-----------------------------------------------
Reply

Marsh Posté le 11-03-2004 à 15:36:14    

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

Reply

Marsh Posté le 11-03-2004 à 15:37:49    

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 )-
Reply

Marsh Posté le 11-03-2004 à 15:48:20    

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!


---------------
-----------------------------------------------
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed