Tento program generuje 6 náhodných čísel mezi 0 a 45 a čísla nelze opakovat. Lze tento kód vylepšit?
$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);
Odpověď
Váš algoritmus je funkční, ale není nutně velmi efektivní a bude se srazovat více a častěji, pokud se počet čísel zvýší.
Je obecně hezčí začít s jedinečnou sadou čísel a extrahovat náhodné výběr těchto čísel namísto výběru náhodných čísel a testování jedinečnosti.
Díky PHP je toto poměrně elegantní, protože má zabudovanou funkci náhodného přehrávání (to v podstatě dělá Fisher-Yatesovo míchání pomocí stejného náhodného systému jako vy).
Takže, získejte pole jedinečných hodnot, zamíchejte je, proveďte výběr a výsledek seřaďte:
$count = 6; $highball = 45; $numbers = range(0, $highball); shuffle($numbers); $drawn = array_slice($numbers, - $count); sort($drawn);
Všimněte si, že použití pojmenovaných proměnných místo konstant dělá je to jasnější, co děláte.
Podívejte se, jak to běží na ideone: https://ideone.com/1Hh0y8
Komentáře
- Generování 6 odlišných čísel ze 45 pravděpodobně nebude vyžadovat více náhodných čísel než zamíchání pole se 45 prvky, a to ani při kolizích. A pochybuji, že 6 a 45 se pro typickou loterii hodně změní.
- @ 200_success – souhlasil, a ačkoli moje první věta zmiňuje účinnost, jde o algoritmus, skutečný bod je o čistotu, a funkce kódu. S výše uvedeným jsou odstraněny také 2 úrovně vnoření a kromě deklarací magického čísla jsou nyní ' pouze 4 řádky kódu.
Odpověď
Proměnnou $i
lze vyloučit, pokud count($numbers)
, což by vyžadovalo změnu operátora z <=
na <
.
while
lze přepsat jako smyčku for
– např.
for ($numbers = []; count($numbers) < 6; /* intentionally empty */ )