Nombre aleatoire sans répitition en java

Fermé
imenenw Messages postés 13 Date d'inscription jeudi 30 août 2012 Statut Membre Dernière intervention 27 décembre 2012 - 6 oct. 2012 à 21:31
 Utilisateur anonyme - 8 oct. 2012 à 17:42
Bonjour à tous,

voilà je veux faire un petit programme en java qui permet de choisir un nombre de 0 à 20 aleatoire sans que celui-ci ne se répete.
pouvez vous m'aider svp?! :(
merci d'avance.

A voir également:

2 réponses

blux Messages postés 26545 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 22 décembre 2024 3 318
6 oct. 2012 à 21:35
Salut,

s'il est aléatoire, alors il peut se répéter...

Par contre, si c'est un "tirage de loto", alors tu dois gérer une chaine de 20 bits, dans lequel tu mettras un bit quand le nombre sort, et lorsque tu tires un nouveau nombre, tu vas vérifier la valeur de ce bit.
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
6 oct. 2012 à 21:51
La manipulation des bits n'est pas super aisée en Java, et puis 20 bits ça va, mais s'il fallait choisir un nombre 0 et 100000 ça deviendrait compliqué à gérer. De toute façon il est nécessaire de conserver l'ordre dans lequel les valeurs ont été récupérées, donc on peux tester si la valeur tirée au sort a été déjà prise et recommencer si nécessaire. Par contre ce n'est pas très pertinent si la densité est élevée (si on tire beaucoup de valeurs parmi les 20) parce qu'il y aurait beaucoup de conflits. Dans ce cas précis il vaut mieux créer une liste avec toutes les valeurs possibles, en choisir une aléatoirement, et la retirer des possibilités quand on l'a choisit pour recommencer.
0
imenenw Messages postés 13 Date d'inscription jeudi 30 août 2012 Statut Membre Dernière intervention 27 décembre 2012
6 oct. 2012 à 21:55
merci blux pour ta réponse mais je ne sais pas comment faire!!! :(
0
blux Messages postés 26545 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 22 décembre 2024 3 318
6 oct. 2012 à 21:58
La manipulation des bits n'est pas super aisée en Java,
Et bien, un tableau a 20 cellules suffira, dans ce cas...

De toute façon il est nécessaire de conserver l'ordre dans lequel les valeurs ont été récupérées,
???

Par contre ce n'est pas très pertinent si la densité est élevée (si on tire beaucoup de valeurs parmi les 20) parce qu'il y aurait beaucoup de conflits.
Tu as mal lu l'énoncé : on ne tire pas des valeurs parmi 20... On veut juste des valeurs entre 0 et 20...

Dans ce cas précis il vaut mieux créer une liste avec toutes les valeurs possibles, en choisir une aléatoirement, et la retirer des possibilités quand on l'a choisit pour recommencer.
On fait la même chose en topant une case d'un tableau à 20 cellules sans gérer la 'suppression des possibilités quand on l'a choisie'...
0
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 3 019
6 oct. 2012 à 22:39
"De toute façon il est nécessaire de conserver l'ordre dans lequel les valeurs ont été récupérées"
Je ne vois pas l'intérêt de tirer successivement des valeurs si on ne conserve pas le résultat.

"On veut juste des valeurs entre 0 et 20"
Oui, ça j'ai bien compris, mais si on en a besoin de 20, il va y avoir beaucoup de conflits pour ne pas trouver de doublons, puisqu'on risque à chaque fois retrouver un nombre déjà tiré (il peut être nécessaire de faire une centaine de tirages aléatoires pour avoir les 20 valeurs différentes).

La "suppression" des possibilités permet de maintenir une durée connue à l'avance du programme, indépendante du tirage aléatoire, puisqu'on aura exactement autant de tirages aléatoires que de valeurs à récupérer (mais avec certes le coût mémoire supplémentaire du deuxième tableau).

/** Choix de k valeurs entre 0 et n-1 */
public static int[] alea1(int k, int n)
{
    boolean[] val = new boolean[n];
    
    int[] tab = new int[k];
    int cpt = 0;
    
    for (int i=0; i<k; i++)
    {
        int r = rand.nextInt(n);
        
        tab[i] = r;
        cpt++;
        
        if (val[r])
            i--;
        else
            val[r]=true;
    }
    
    System.out.printf("Nombre de 'random' : %d\n",cpt);
    return tab;
}

/** Choix de k valeurs entre 0 et n-1 */
public static int[] alea2(int k, int n)
{
    int[] val = new int[n];
    for (int i=0; i<n; i++)
        val[i]=i;
    
    int[] tab = new int[k];    
    int cpt = 0;
    
    for (int i=0; i<k; i++)
    {
        int r = rand.nextInt(n-i);
        cpt++;
        
        tab[i] = val[r];
        val[r] = val[n-i-1];
    }
    
    System.out.printf("Nombre de 'random' : %d\n",cpt);
    return tab;
}

private static void afficher(int[] tab)
{
    for (int i : tab)
        System.out.printf("%d,",i);
    System.out.println();
}

public static void main(String...args)
{
    afficher(alea1(20,20));
    afficher(alea2(20,20));
}
0
blux Messages postés 26545 Date d'inscription dimanche 26 août 2001 Statut Modérateur Dernière intervention 22 décembre 2024 3 318
6 oct. 2012 à 22:47
Je ne vois pas l'intérêt de tirer successivement des valeurs si on ne conserve pas le résultat.
Tu parles de conserver l'ordre des résultats et ensuite de conserver les valeurs, avoue que ce n'est pas la même chose...

(il peut être nécessaire de faire une centaine de tirages aléatoires pour avoir les 20 valeurs différentes).
Sûrement, mais en durée, ça fait combien de microsecondes ?

Ton code est quand même sacrément compliqué pour une demande aussi simple...
0
Utilisateur anonyme
8 oct. 2012 à 17:42
Salut,

Tu peux tester cette méthode ( nombresAlea(int mini, int maxi) ), volontairement détaillée, et dans ce petit programme de test.

   import java.util.Random;
   import java.util.Arrays; // pour trier le tableau tab

   
   public class TestNombresAleatoirs
   {
      private static int tab[];
   
      //public static int[] nombresAlea(int mini, int maxi)
      public static void nombresAlea(int mini, int maxi)
      {
      // min et max devront être dans les limites ci-dessous
         int miniInteger = Integer.MIN_VALUE;
         int maxiInteger = Integer.MAX_VALUE;
         //System.out.println("miniInteger/maxiInteger = " + miniInteger + "/" + maxiInteger);
      
         int min = mini;
         int max = maxi;
         
         int nbreVal = ((max - min) +1); // sera la taille du tableau.
      
         tab = new int[nbreVal]; // est initialisé a 0 par défaut
         
      // Il faut initialiser le tableau à une valeur hors min/max
         int valInit = min -1; // ou bien max +1
         
      // on l'initialise à min -1 (ou à max +1) sinon le num. éventuel 0 serait un doublon   
         for (int i = 0; i <nbreVal; i++)
            tab[i] = valInit;
      
         int i1 = 0;
         int i2 = 0;
         boolean encore = true;
      
         while(encore)
         {
            for (i1 = 0; i1 <nbreVal; i1++)
            {
               encore = false; // sera forcé true si doublon
               Random r = new Random();
               int aI = min + r.nextInt(nbreVal);
               
               for (i2 = 0; i2 <nbreVal; i2++)
               {
                  if (aI == tab[i2]) // doublon ?
                  {
                     encore = true;
                     //System.out.println("Le nouveau num. obtenu:\n" + aI
                        //+ " est un doublon, on ne le prend pas.(i2 = " + i2 + ")\n");
                     i1--;
                     break;
                  }
               }
               
               if (encore == false)
                  tab[i1] = aI;   // ou bien, utilisation immédiate
            }
         }
        //return tab; // si la méthode nombresAlea(...) est dans une classe externe
      }
   
      public static void main(String args[])
      {
         int mini = 0;
         int maxi = 20;
         nombresAlea(mini, maxi); // prévoir la saisie de mini et maxi
          
         //Arrays.sort(tab);
         // Le tri ci-dessus est fait pour contrôler facilement qu'on a bien tous les nombres attendus
         // surtout s'il sont nombreux puisqu'ils sont rangés dans tab[] dans un ordre ... aléatoire
      	// Ne pas trier en utilisation normale
         
         for (int i = 0; i <tab.length; i++)
         {
            System.out.println("num. " + (i +1) + ": " + tab[i]);
         }
      }
   }

-1