Ez a program 6 véletlen számot generál 0 és 45 között, és a számokat nem lehet megismételni. Javítható ez a kód?
$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);
Válasz
Az algoritmus működőképes, de nem feltétlenül túl hatékony, és többször ütközik, és gyakrabban ütközik, ha a számok száma növekszik.
Általában rendesebb egyedi számkészlettel kezdeni és véletlenszerűt kivonni ezeknek a számoknak a kiválasztása a véletlenszerű számok kiválasztása helyett és az egyediség tesztelése.
A PHP ezt viszonylag ügyessé teszi, mert beépített shuffle funkcióval rendelkezik. (ez lényegében egy Fisher-Yates keverést folytat ugyanazzal a véletlenszerű rendszerrel, mint te).
Tehát, szerezzen be egy tömböt az egyedi értékekből, keverje össze, válasszon ki és rendezze az eredményt:
$count = 6; $highball = 45; $numbers = range(0, $highball); shuffle($numbers); $drawn = array_slice($numbers, - $count); sort($drawn);
Megjegyzés: konstansok helyett megnevezett változók használata világosabb, amit csinálsz.
Lásd ezt az ideone-on: https://ideone.com/1Hh0y8
Megjegyzések
- A 45-ből 6 különálló szám előállításához valószínűleg nincs szükség több véletlenszerű számra, mint egy 45 elemű tömb keverése, még ütközések esetén sem. És kétlem, hogy a 6 és a 45 sokat fog változni, egy tipikus sorsolás esetén.
- @ 200_success – egyetértett, és bár első mondatom a hatékonyságot említi, ez az algoritmusról szól, az igazi lényeg a tisztaság, és a kód funkciója. A fészkelés 2 szintjét a fentiek is eltávolítják, és a mágikus szám deklarációkat leszámítva ' ez már csak 4 kódsor.
Válasz
A $i
változó kiküszöbölhető, ha count($numbers)
helyett használták, ami megköveteli, hogy az operátor <=
helyett <
legyen megváltoztatva.
A while
átírható for
ciklusként – pl.
for ($numbers = []; count($numbers) < 6; /* intentionally empty */ )