Template de vecteur avec tirage aleatoire (c++)

Soyez le premier à donner votre avis sur cette source.

Vue 7 591 fois - Téléchargée 230 fois

Description

Ce template donne une structure de vecteur avec possibilité de faire des tirages aleatoires dans celui-ci (il peut servir par exemple a faire du scheduling).

Fonctions disponibles :
- constructeur avec taille du vecteur en paramètre
- destructeur
- fonction d'ajout d'un élément dans le vecteur
- fonction de suppression d'un élément dans le vecteur
- fonction de tirage d'un élément dans le vecteur

Attention ! on ne peut pas modifier les éléments du vecteur si on a commencé à faire des tirages aléatoires et que tous les éléments du vecteur n'ont pas encore été tirés.

Il faut savoir également que la structure choisie est un tableau et que des décalages sont faits à chaque modification ou chaque tirage aléatoire. Il ne faut donc pas l'utiliser avec un nombre d'éléments trop important.

(j'utilise une fonction "random" définie dans les fichiers qui vont bien).

Source / Exemple :


#include "rand.hpp"
#include <iostream>

using namespace std;

//------------------------------------------------------------------------------
//   Template pour structure de vecteur avec fonctionnalite
//      de tirage aleatoire
//
//------------------------------------------------------------------------------
template <class T>
class AleaVect
{
   protected :
      int _sizeMax; // nombre maximal d'elements
      int _size;    // nombre d'elements actuels
      int _state;   // etat : 0 -> on peut ajouter/enlever des elements
                    //        1 -> on est en cours de tirage dans la vecteur
      T * _vect1;   // vecteur complet (etat 0)
                    // ou contenant les elements non encore tires (etat 1)
      T * _vect2;   // vecteur contenant les elements tires
      int _size1;   // nbre d'elements dans le vecteur 1
      int _size2;   // nbre d'elements dans le vecteur 2
      
   public :
      AleaVect(int inSizeMax); // constructeur
      ~AleaVect();             // destructeur
      int Ajoute(T inType);    // ajout d'un element
      int Enleve(T inType);    // retrait d'un element
      T Alea();                // tirage aleatoire d'un element
};

//------------------------------------------------------------------------------
//   Constructeur
//
//   inSizeMax : nombre maximal d'elements du vecteur
//
//------------------------------------------------------------------------------
template <class T>
AleaVect<T>::AleaVect(int inSizeMax)
{
   _sizeMax = inSizeMax;
   _size = 0;
   _vect1 = new T[inSizeMax];
   _vect2 = new T[inSizeMax];
   _state = 0;
}

//------------------------------------------------------------------------------
//   Destructeur
//
//------------------------------------------------------------------------------
template <class T>
AleaVect<T>::~AleaVect()
{
   delete[] _vect1;
   delete[] _vect2;
}

//------------------------------------------------------------------------------
//   Fonction d'ajout d'un element
//
//   inType : element a ajouter
//   retourne 0 si on peut ajouter et 1 sinon
//
//------------------------------------------------------------------------------
template <class T>
int AleaVect<T>::Ajoute(T inType)
{
   if(_size<_sizeMax && _state==0)
   {
      _vect1[_size++]=inType;
      return 0;
   }
   return 1;
}

//------------------------------------------------------------------------------
//   Fonction de retrait d'un element
//
//   inType : element a retirer
//   retourne 0 si retrait effectue et 1 si l'element n'etait pas present
//
//------------------------------------------------------------------------------
template <class T>
int AleaVect<T>::Enleve(T inType)
{
   bool trouve = false;
   int i = 0;
   
   if(state==0) // si nous ne sommes pas en cours de tirage
   {
      while(!trouve && i<_size) // parcours du vecteur
      {
         if(_vect1[i] == inType)
            trouve = true;
         else
            i++;
      }
   
      if(trouve) // si l'element est present
      {
         for(int j = i ; j<_size-1 ; j++) // decalage du vecteur pour effacer
            _vect1[j] = _vect1[j+1];
         _size--;
         return 0; // element efface
      }
   }
   return 1; // non trouve
}

//------------------------------------------------------------------------------
//   Fonction de tirage d'un element
//     (attention : le vecteur ne doit etre vide)
//
//   retourne l'element tire
//
//------------------------------------------------------------------------------
template <class T>
T AleaVect<T>::Alea()
{
   T res; // variable contenant le resultat;
   
   if(_state == 0) // si on est pas en phase de tirage
   {
      _state = 1; // on se met en etat de tirage aleatoire
      _size1 = _size;
      _size2 = 0;
   }

   int r = random(0, _size1); // tirage d'un index aleatoire

   res = _vect1[r]; // on transfere dans le vecteur 2
   _vect2[_size2] = res;

   for(int j = r ; j<_size1-1 ; j++) // decalage du vecteur
      _vect1[j] = _vect1[j+1];

   _size1--; // reactualisation des tailles des vecteurs
   _size2++;

   if(_size1 == 0) // si tous les elements ont ete tires
   {
      T * temp;
      temp = _vect1;
      _vect1 = _vect2;
      _vect2 = temp;

      _state = 0;
   }

   return res; // element aleatoire
}

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

cs_exar
Messages postés
287
Date d'inscription
vendredi 5 décembre 2003
Statut
Membre
Dernière intervention
22 avril 2012
1 -
Plus court avedc la STL:

#ifndef __VECTORALEA_H__
#define __VECTORALEA_H__
#include <vector>
#include 
using namespace std;

template<class T>
class VectorAlea: public vector<T>{
public:
   T Alea();
};

template<class T>
T VectorAlea<T>::Alea(){
   VectorAlea<T> tmp=*this;
   random_shuffle(tmp.begin(), tmp.end());
   T ret=tmp.back();
   tmp.pop_back();
   *this=tmp;
   return ret;
}

#endif


Pour tester:
#include <cstdlib>
#include 
#include "vectoralea.h"

using namespace std;

int main(int argc, char *argv[])
{
    VectorAlea tst;
    for(int cnt=1; cnt<=10; cnt++)
      tst.push_back(cnt);
    for(int cnt=0; cnt<10; cnt++)
      cout<<tst.at(cnt)<<endl;
    cout<<"************************"<<endl;
    for(int cnt=0; cnt<10; cnt++)
      cout<<tst.Alea()<<endl;
    return EXIT_SUCCESS;
}


Sinon, code bien propre !
A+!

*********
«Asseyez-vous une heure près d’une jolie fille, cela passe comme une minute. Asseyez-vous une minute sur un poêle brûlant, et cela passe comme une heure. C’est cela la relativité.»

Albert Einstein.
cs_exar
Messages postés
287
Date d'inscription
vendredi 5 décembre 2003
Statut
Membre
Dernière intervention
22 avril 2012
1 -
Au fait, j'ai fait ça en deux minutes, il faut contrôler que le vecteur n'est pas vide avant de tenter de renvoyer une valeur...
Bon courage !

*********
«Asseyez-vous une heure près d'une jolie fille, cela passe comme une minute. Asseyez-vous une minute sur un poêle brûlant, et cela passe comme une heure. C'est cela la relativité.»

Albert Einstein.
cs_Sunglasses
Messages postés
8
Date d'inscription
samedi 20 mai 2006
Statut
Membre
Dernière intervention
11 juillet 2008
-
C'est sûr qu'on peut réutiliser ce qui existe déjà, mais je fais ça pour apprendre et pour m'entrainer (Et puis aussi parce que j'aime bien réinventer la roue, oui, je l'avoue :-) ).

Faudra que je m'intéresse de plus près à la STL.

En tout cas merci du commentaire !
cs_exar
Messages postés
287
Date d'inscription
vendredi 5 décembre 2003
Statut
Membre
Dernière intervention
22 avril 2012
1 -
Oui, c'est sur !
A noter que tu peux également utiliser ta propore fonction random.
Exemple:

#include
#include <functional>
#include <vector>

...

using namespace std;

ptrdiff_t random(prtdiff_t i){
return srand()%i;
}

ptrdiff_t (*prandom)(ptrdiff_t)=random;

int main(){
vector v;
// ici, on remplit le vecteur

// appel de random_shuffle
random_shuffle(v.begin(), v.end(), prandom);

...

}

Vraiment, je te conseille d t'intéresser à la STL, c'est très pratique !
Bonne continuation !
cs_Sunglasses
Messages postés
8
Date d'inscription
samedi 20 mai 2006
Statut
Membre
Dernière intervention
11 juillet 2008
-
J'utilise déjà ma propre fonction random :-) (voir dans les fichiers rand.cpp et rand.hpp). C'est une petite bibliothèque de fonctions aléatoire qu'on nous avait fait faire en TP mais j'ai juste laissé la fonction dont j'avais besoin dans mon programme.

Merci !
Commenter la réponse de cs_juju12

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.