2009-11-04 23 views
5

Voglio generare numeri casuali da -n a n escludendo 0. Qualcuno può fornirmi il codice in C? Come escludere 0?Generazione di numeri casuali da -n a n in C

+1

Perché il voto negativo? Vorrei che questo sito costringesse le persone ad aggiungere un commento quando hanno votato. –

risposta

9

Un'idea potrebbe essere quella di generare un numero casuale x nell'intervallo [1,2n], incluso. Quindi restituire -(x - n) per x superiore a n, altrimenti è sufficiente restituire x.

Questo dovrebbe funzionare:

int my_random(int n) 
{ 
    const int x = 1 + rand()/(RAND_MAX/(2 * n) + 1); 

    return x > n ? -(x - n) : x; 
} 

Vedere la comp.lang.c FAQ per ulteriori informazioni su come utilizzare in modo sicuro rand(); spiega l'uso di cui sopra.

+0

Grazie. Chris ha appena postato la risposta prima di te, quindi l'ho fatto. – avd

3

La cosa più semplice che posso suggerire di fare è di generare un numero casuale compreso tra 0 e 2n e poi fare il trucco per la matematica:

result= n - randomNumber 

Sebbene 0 potrebbe essere molto improbabile è possibile verificare la presenza che l'utilizzo di un Se e ripristina la generazione del numero casuale.

1
int random(int N) 
{ 
    int x; 
    do{ 
    x=rand()%(N*2+1)-N; 
    }while(x==0); 
    return x; 
} 

Si sceglie un numero da -N a N, ma mantiene a farlo se si tratta di 0.

Un'alternativa, come suggerito nei commenti, genera un numero compreso tra -N e N-1 e lo incrementa se positivo o 0:

int random(int N) 
{ 
    int x;  
    x=rand()%(N*2)-N; 
    if(x>=0) x++; 
    return x; 
} 
+1

Un do-while dipendente da un valore casuale potrebbe essere eseguito per molto, molto tempo! Ma potresti liberarti del tempo di esecuzione non deterministico riducendo di 1 l'intervallo del risultato casuale, quindi convertendo artificialmente qualsiasi risultato 0 al risultato del confine mancante. Nessun ciclo necessario. –

+0

Non sono d'accordo con la tua affermazione che ci vorrebbe un "molto, molto tempo": la quota di x è 0 (e quindi, il ciclo ripetuto) è 1/(2N + 1), che è abbastanza piccolo per grande Valori di N. Tuttavia, ho inserito il tuo suggerimento nella mia risposta, che ritengo offra una soluzione migliore per questo particolare problema, quindi grazie :) – Wernsey

+0

Ah ... Non ho detto che "ci" ci vorrebbe un lungo tempo, ma piuttosto che "potrebbe" richiedere molto tempo. C'è una differenza! :) Mi scuso se questo sembra sfacciato. Lavoro in software in tempo reale, dove tutto ciò che non può assolutamente essere garantito per terminare in un determinato tempo deterministico "potrebbe richiedere molto tempo". Tecnicamente parlando, la tua prima versione è O (?) E la tua seconda versione è O (1) (o, nel peggiore dei casi, non più complessa di "rand"). Quindi in termini di determinismo, la tua seconda versione è un grande miglioramento. Ben fatto, btw. Il mio suggerimento "converti il ​​0 al confine" non sarebbe stato così carino. –

Problemi correlati