[C++] random_shuffle ne randomize pas

random_shuffle ne randomize pas [C++] - C++ - Programmation

Marsh Posté le 04-12-2004 à 12:04:54    

Salut,
malgré un appel à random_shuffle de la manière suivante :
 

Code :
  1. A::A()
  2. {
  3. v.push_back(B(0));
  4. v.push_back(B(1));
  5. v.push_back(B(2));
  6. v.push_back(B(3));
  7. random_shuffle(v.begin(), v.end());
  8. for(vector<B>::const_iterator it=v.begin(); it!=v.end(); it++)
  9.    cout << static_cast<B>(*it).toString() << endl;
  10. }


 
je vois à l'affichage que les objets ne sont pas mélangés...
dans la classe A, vector<B> v;
je ne comprends pas pourquoi. de plus est-ce que mon itération est faite manière correcte pour l'affichage ?
merci


Message édité par antsite le 04-12-2004 à 13:13:42
Reply

Marsh Posté le 04-12-2004 à 12:04:54   

Reply

Marsh Posté le 04-12-2004 à 12:58:10    

Code :
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <iterator>
  4. template<typename T, size_t N>
  5. inline T* begin(T (&t)[N])
  6. {
  7.   return t;
  8. }
  9. template<typename T, size_t N>
  10. inline T* end(T (&t)[N])
  11. {
  12.   return t + N;
  13. }
  14. int main()
  15. {
  16.   int data[] = {1, 2, 3, 4, 5};
  17.   std::copy(begin(data), end(data), std::ostream_iterator<int>(std::cout, " " ));
  18.   std::cout << std::endl;
  19.   std::random_shuffle(begin(data), end(data));
  20.   std::copy(begin(data), end(data), std::ostream_iterator<int>(std::cout, " " ));
  21.   std::cout << std::endl;
  22. }

Reply

Marsh Posté le 04-12-2004 à 13:30:45    

mais je comprends pas, le code marche pour un tableau d'entier comme data[], mais avec mon vecteur rempli d'objets B. Qu'est-ce qui pourrait bien faire échouer le random_shuffle ? j'ai vérifié que begin() retourne bien le premier élément, à priori c'est bon.

Reply

Marsh Posté le 04-12-2004 à 13:36:55    

Allez, t'en crève d'envie, fais péter le code de B. Je suis sûr qu'on va trouver des trucs qui manquent (constructeur de recopie, opérateur d'affectation, etc.).

Reply

Marsh Posté le 04-12-2004 à 13:46:07    

Code :
  1. class B
  2. {
  3. public:
  4.   enum letype {Toto, Titi, Tata};
  5.   B(char _c, letype _t) : c(_c), t(_t) {}
  6.   string toString() const;
  7.   bool operator==(const B& droit) { return (c == droit.c) && (t == droit.t); }
  8. private:
  9.   char c;
  10.   letype t;
  11. };


 
voilou,
sinon j'ai essayé quand j'appelle 2fois de suite le random, le dernier élément de vecteur arrive en premier dans le vecteur...


Message édité par antsite le 04-12-2004 à 14:08:56
Reply

Marsh Posté le 04-12-2004 à 13:49:07    

Et si tu lui met un constructeur de copie, ça donne quoi ?

Reply

Marsh Posté le 04-12-2004 à 13:51:01    

ben je comprend pas à quoi il sert, celui par défaut il fait pas l'affaire ? y a pas d'alloc dynamique...

Reply

Marsh Posté le 04-12-2004 à 13:51:48    

/me summons Taz.

Reply

Marsh Posté le 04-12-2004 à 13:54:42    

une petite explication quant à la nécessité de ce constructeur serait la bienvenue :)
 
edit:
j'ai rajouté ça sans en être convaincu, ça change rien

Code :
  1. B(const B& b)
  2.     {
  3.       c = b.c;
  4.       t = b.t;
  5.     }



Message édité par antsite le 04-12-2004 à 13:59:42
Reply

Marsh Posté le 04-12-2004 à 14:01:11    

pourquoi tu static_cast ?

Reply

Marsh Posté le 04-12-2004 à 14:01:11   

Reply

Marsh Posté le 04-12-2004 à 14:05:14    

bof, je vois pas l'utilité de ça ni comment ça pourrait changer quoi que ce soit. on fait ça dans operator= pour éviter de perdre des données. Dans le constructeur, je vois pas.
 
Si ta classe est de type POD, les constructeurs par recopie, affectation devrait être bon. Mais c'est quoi le code de ta fonction membre tostring ?

Reply

Marsh Posté le 04-12-2004 à 14:08:13    

Taz a écrit :

pourquoi tu static_cast ?


 
tout à fait, je l'ai viré, et ça m'a fait penser à déclarer une méthode const pour que ça marche.
enfin ça randomize toujours pas

Reply

Marsh Posté le 04-12-2004 à 14:09:07    

c'est ta classe qui est mitée. File ta classe __COMPLÈTE__

Reply

Marsh Posté le 04-12-2004 à 14:09:57    

Code :
  1. string B::toString() const
  2. {
  3.   string s;
  4.   s.append(1, c);
  5.   switch(t)
  6.   {
  7.   case Toto: s += "a"; break;
  8.   case Titi: s += "b"; break;
  9.   case Tata: s += "c"; break;
  10.   }
  11.   return s;
  12. }

Reply

Marsh Posté le 04-12-2004 à 14:10:47    

D'ailleurs, c'est pas louche que le compilo accepte de caster le truc pointé par un const_iterator en B (non const) ?

Reply

Marsh Posté le 04-12-2004 à 14:17:56    

Code :
  1. #include <string>
  2. class B
  3. {
  4. public:
  5.   enum letype {Toto, Titi, Tata};
  6.   B(char _c, letype _t) : c(_c), t(_t) {}
  7.   std::string toString() const;
  8. private:
  9.   char c;
  10.   letype t;
  11. };
  12. std::string B::toString() const
  13. {
  14.   // revoit les string, tout ça est pas terrible
  15.   std::string s;
  16.   s.append(1, c);
  17.   switch(t)
  18.     {
  19.     case Toto: s += "a"; break;
  20.     case Titi: s += "b"; break;
  21.     case Tata: s += "c"; break;
  22.     }
  23.   return s;
  24. }
  25. #include <vector>
  26. #include <algorithm>
  27. #include <iostream>
  28. void print(const std::vector<B> &values)
  29. {
  30.   for(size_t i = 0; i < values.size(); ++i)
  31.     std::cout << values[i].toString() << ' ';
  32.   std::cout << std::endl;
  33. }
  34. int main()
  35. {
  36.   std::vector<B> values;
  37.   values.push_back( B('T', B::Toto) );
  38.   values.push_back( B('a', B::Tata) );
  39.   values.push_back( B('z', B::Titi) );
  40.   print(values);
  41.   std::random_shuffle(values.begin(), values.end());
  42.   print(values);
  43. }


 

Citation :

Ta ac zb  
Ta zb ac

Reply

Marsh Posté le 04-12-2004 à 14:31:40    

bordel je comprends pas, y a toujours juste le dernier élément du vecteur qui passe premier et c'est le seul changement...
 
je précise que ce fait taz dans le main, moi je le fais dans le constructeur de la classe contenant le fameux vecteur à shuffler.


Message édité par antsite le 04-12-2004 à 14:32:57
Reply

Marsh Posté le 04-12-2004 à 14:32:33    

ah ben si après t'as un problème de combinatoire ... tu crois qu'il y a combien d'arrangement de 3 éléments ?

Reply

Marsh Posté le 04-12-2004 à 14:35:08    

oui mais moi j'en ai mis 5 par exemple

Reply

Marsh Posté le 04-12-2004 à 14:36:44    

et ben refais encore un shuffle dessus

Reply

Marsh Posté le 04-12-2004 à 14:39:23    

et bien du coup on décale encore d'un rang :
au début j'avais a b c d e
après 1 shuffle : e a b c d
après 1 shuffle : d e a b c

Reply

Marsh Posté le 04-12-2004 à 14:41:24    

et alors ? il est pù le problème ?

Reply

Marsh Posté le 04-12-2004 à 14:43:12    

ben le problème c'est qu'avec 50 éléments c'est pareil, alors à moins que j'ai pas bien compris ce que fait shuffle, ça ne me satisfait pas comme "randomization" du vecteur ?

Reply

Marsh Posté le 04-12-2004 à 14:48:11    

ce qui est bizarre, c'est que ton random_shuffle, on dirait next_permutation
 
c'est quoi ta STL ?
 
edit:

Code :
  1. values.push_back( B('T', B::Toto) );
  2.   values.push_back( B('a', B::Tata) );
  3.   values.push_back( B('z', B::Titi) );
  4.   values.push_back( B('F', B::Toto) );
  5.   values.push_back( B('o', B::Tata) );
  6.   values.push_back( B('r', B::Titi) );
  7.   values.push_back( B('E', B::Toto) );
  8.   values.push_back( B('v', B::Tata) );
  9.   values.push_back( B('e', B::Titi) );
  10.   values.push_back( B('r', B::Titi) );

et moi je voudrais que tu testes mon exemple avec tout ça, voir ce que te donne un random_shuffle dessus


Message édité par Taz le 04-12-2004 à 14:50:38
Reply

Marsh Posté le 04-12-2004 à 14:55:21    

oh mais c'est que tu aurais bien raison sur ce doute :
je viens de compiler en ssh à la fac, et ça shuffle bien !
> ma version de STL serait-elle obsolète ?

Reply

Marsh Posté le 04-12-2004 à 14:57:02    

t'as quoi ?

Reply

Marsh Posté le 04-12-2004 à 15:00:33    

Ta ac zb Fa oc rb Ea vc eb rb
rb Ta ac zb Fa oc rb Ea vc eb

Reply

Marsh Posté le 04-12-2004 à 15:06:46    

comme version :o

Reply

Marsh Posté le 04-12-2004 à 15:11:51    

mais comment je le vois ? le rep qui contient les include c'est 3.3.3 il me semble maintenant la STL je sais comment le savoir...

Reply

Marsh Posté le 04-12-2004 à 15:14:02    

mais PUTAIN t'as quoi comme compilateur / libstdc++, packagé par qui etc ? ça fait 2 jours qu'on tourne autour du pot, j'en ai marre. T'as qu'à envoyer un rapport de bug à qui te fournit ton compilateur, moi j'en ai ma claque.

Reply

Marsh Posté le 04-12-2004 à 15:22:56    

tout ce que je peux te dire en regardant les packages installés  de cygwin :
gcc-g++ 3.3.3-3
de plus il me semble que cygwin utilise mingw.
voila maintenant j'en sais pas plus...

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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