2011-02-04 2 views
5

Come parte del mio progetto, ho bisogno di creare numeri casuali non ripetuti a 2 o 3 cifre dando una serie di numeri. Non voglio implementare una lista o un array per questo, dal momento che dovrei ottenere 1 numero casuale per ogni chiamata di funzione.Numeri casuali non ripetuti

Ho provato a farlo utilizzando la classe SecureRandom di Java. Ho ricevuto aiuto anche da alcuni dei siti, ma sono bloccato nel mezzo, possiamo mescolare i VALORI e farlo fare? Ma non so come potrebbe essere fatto. Qualcuno può aiutarmi?

import java.security.SecureRandom; 
public class RandomNumber { 
private static final RandomNumber rnd= new RandomNumber(); 

    private static final char[] VALUES = new char[] { 
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; 
    private static final SecureRandom srn= new SecureRandom(); 
    public String createID() 
    { 
     byte[] bytes = new byte[3]; 
     srn.nextBytes(bytes); 

    } 
+1

Sono le cifre all'interno del numero che dovrebbe essere non ripetibile o i numeri 2 o 3 risultanti? La tua domanda mescolantesi suggerisce la prima, ma quest'ultima sembrerebbe più un compito a casa. –

+0

Non ripetibili come in nessun numero successivo sono uguali o globalmente non ripetibili? – biziclop

+0

No..Paul .... Le cifre all'interno del numero possono essere ripetute ... Ma i numeri generati per ogni chiamata dovrebbero essere unici ... (ad esempio: 331 è possibile ... ma 331 non dovrebbe essere generato secondo ora ...) – vidhya

risposta

12

Fisher-yates shuffle algorithm è la strada da percorrere. È efficiente per mischiare. e funziona in tempo lineare.

qui è algo

To shuffle an array a of n elements: 
    for i from n − 1 downto 1 do 
     j ← random integer with 0 ≤ j ≤ i 
     exchange a[j] and a[i] 

e il codice

for(int i=VALUES.length-1; i>0; i--){ 
      int rand = (int) (Math.random()*i); 
      char temp = VALUES[i]; 
      VALUES[i] = VALUES[rand]; 
      VALUES[rand] = temp; 
    } 
+0

Grazie Manoj ... ma l'output del programma di cui sopra sarebbe un array ... ok ..? Allora come posso ottenere un valore singolo per ogni chiamata di funzione ogni volta ..? – vidhya

+0

@vidhya: semplicemente metti tutti i ~ 1000 valori possibili in un array e shuffle. Quindi tutto quello che devi fare è tenere una variabile per tenere traccia di quanti numeri hai prodotto fino ad ora, e continuare a recuperare quello successivo nell'array shuffled. –

-2

Quando itera codice di Manoj è più probabile per scambiare gli elementi inferiori di valori [], piuttosto che quelle più alte. Es: Per i = 9 c'è una possibilità 1/10 di scambiare qualsiasi membro dell'array (incluso se stesso). Quindi per i = 8 non possiamo mai scambiare con VALUES [9] di nuovo perché Math.random() * posso spaziare solo da 0 a 8. Ciò significa che i VALORI [9] saranno uguali ai VALORI ORIGINALI [9] più spesso di qualsiasi l'altro elemento sarà uguale al suo rispettivo elemento (e così via con l'aumentare della probabilità di essere scambiato mentre divento più piccolo).

vorrei semplicemente per correggere la risposta di cui sopra per non appesantire gli elementi dell'array:

for(int i=0; i <= VALUES.length - 1; i++){ 
     int rand = (int) (Math.random()*(VALUES.length-1)); 
     char temp = VALUES[i]; 
     VALUES[i] = VALUES[rand]; 
     VALUES[rand] = temp; 

volte VALUES.length Ora viene eseguita la riproduzione casuale (o tutte le volte che ti piace) e non favorire qualsiasi particolare elemento dell'array.

+2

In realtà, il tuo "bugfix" introduce un bug. Questo è un malinteso comune che è persino [discusso] (http://en.wikipedia.org/wiki/Fisher-Yates#Implementation_errors) su wikipedia. – meriton