Dette programmet genererer 6 tilfeldige tall mellom 0 og 45, og tallene kan ikke gjentas. Kan denne koden forbedres?
$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);
Svar
Algoritmen din er funksjonell, men er ikke nødvendigvis veldig effektiv, og det vil kollidere mer, og oftere hvis antall tall øker.
Det er generelt bedre å starte med et unikt sett med tall, og å trekke ut et tilfeldig valg av disse tallene, i stedet for å velge tilfeldige tall, og teste for unikhet.
PHP gjør dette relativt pent, fordi det har en innebygd shuffle-funksjon (som i hovedsak gjør en Fisher-Yates shuffle ved hjelp av det samme tilfeldige systemet som du er).
Så, få et utvalg av unike verdier, bland det, ta et utvalg av det, og sorter resultatet:
$count = 6; $highball = 45; $numbers = range(0, $highball); shuffle($numbers); $drawn = array_slice($numbers, - $count); sort($drawn);
Merk, ved å bruke navngitte variabler i stedet for konstanter gjør det er tydeligere hva du gjør.
Se dette på ideone: https://ideone.com/1Hh0y8
Kommentarer
- Å generere 6 forskjellige tall av 45 trenger sannsynligvis ikke flere tilfeldige tall enn å blande en 45-element-matrise, selv ikke med kollisjoner. Og jeg tviler på at 6 og 45 vil endre seg mye, for et typisk lotteri.
- @ 200_success – avtalt, og selv om min første setning nevner effektivitet, handler det om algoritmen, det virkelige poenget handler om ryddighet, og funksjon av koden. To nivåer av hekking fjernes også med det ovennevnte, og unntatt de magiske nummererklæringene, er det ' bare fire linjer med kode.
Svar
Variabelen $i
kan elimineres hvis count($numbers)
ble brukt i stedet, noe som ville kreve at operatøren ble endret fra <=
til <
.
while
kan skrives om som en for
sløyfe – f.eks.
for ($numbers = []; count($numbers) < 6; /* intentionally empty */ )