Dette program genererer 6 tilfældige tal mellem 0 og 45, og tallene kan ikke gentages. Kan denne kode 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
Din algoritme er funktionel, men er ikke nødvendigvis meget effektiv, og det kolliderer mere og oftere, hvis antallet af tal stiger.
Det er generelt pænere at starte med et unikt sæt tal og udtrække et tilfældigt valg af disse tal i stedet for at vælge tilfældige tal og teste for unikhed.
PHP gør dette relativt pænt, fordi det har en indbygget shuffle-funktion (at “i det væsentlige laver en Fisher-Yates shuffle ved hjælp af det samme tilfældige system, som du er).
Så, få en matrix af de unikke værdier, bland den, tag et valg af den, og sorter resultatet:
$count = 6; $highball = 45; $numbers = range(0, $highball); shuffle($numbers); $drawn = array_slice($numbers, - $count); sort($drawn);
Bemærk, ved hjælp af navngivne variabler i stedet for konstanter gør det er tydeligere, hvad du laver.
Se dette kører på ideone: https://ideone.com/1Hh0y8
Kommentarer
- At generere 6 forskellige tal ud af 45 behøver sandsynligvis ikke flere tilfældige tal end at blande et array med 45 elementer, selv ikke med kollisioner. Og jeg tvivler på, at 6 og 45 vil ændre sig meget for et typisk lotteri.
- @ 200_succes – aftalt, og selvom min første sætning nævner effektivitet, det handler om algoritmen, handler det virkelige om pæne og funktion af koden. 2 niveauer af indlejring fjernes også med ovenstående, og eksklusive de magiske nummererklæringer er det ' nu kun 4 linier kode.
Svar
Variablen $i
kunne elimineres, hvis count($numbers)
blev brugt i stedet, hvilket ville kræve, at operatøren blev ændret fra <=
til <
.
while
kunne omskrives som en for
-sløjfe – f.eks.
for ($numbers = []; count($numbers) < 6; /* intentionally empty */ )