Questo programma genera 6 numeri casuali tra 0 e 45 e i numeri non possono essere ripetuti. Questo codice può essere migliorato?
$numbers = []; $i = 1; while($i <= 6) { $number = mt_rand(0, 45); if(!in_array($number, $numbers)) { array_push($numbers, $number); $i++; } } sort($numbers); echo implode(" - ", $numbers);
Risposta
Il tuo algoritmo è funzionante, ma non è necessariamente molto efficiente e si scontrerà di più, e più spesso se il conteggio dei numeri aumenta.
In genere è più ordinato iniziare con un insieme unico di numeri ed estrarre un selezione di quei numeri, invece di selezionare numeri casuali e testarne lunicità.
PHP lo rende relativamente pulito, perché ha una funzione di riproduzione casuale incorporata (che “essenzialmente sta facendo un Fisher-Yates shuffle utilizzando lo stesso sistema casuale che sei tu).
Quindi, ottenere un array di valori univoci, mescolarlo, selezionarlo e ordinare il risultato:
$count = 6; $highball = 45; $numbers = range(0, $highball); shuffle($numbers); $drawn = array_slice($numbers, - $count); sort($drawn);
Nota, luso di variabili con nome invece di costanti rende è più chiaro quello che stai facendo.
Vedi questo in esecuzione su ideone: https://ideone.com/1Hh0y8
Commenti
- È probabile che la generazione di 6 numeri distinti su 45 non richieda più numeri casuali rispetto a mescolare un array di 45 elementi, anche in caso di collisioni. E dubito che 6 e 45 cambieranno molto, per una tipica lotteria.
- @ 200_success – daccordo, e sebbene la mia prima frase menzioni lefficienza, che riguarda lalgoritmo, il vero punto è sulla pulizia, e funzione del codice. Anche 2 livelli di nidificazione vengono rimossi con quanto sopra ed escludendo le dichiarazioni dei numeri magici, ' ora sono solo 4 righe di codice.
Risposta
La variabile $i
potrebbe essere eliminata se count($numbers)
è stato invece utilizzato, il che richiederebbe la modifica delloperatore da <=
a <
.
Il while
potrebbe essere riscritto come un for
loop, ad es.
for ($numbers = []; count($numbers) < 6; /* intentionally empty */ )