PHP – losowanie liczb bez powtórzeń

Data dodania: jakiś czas temu
reklama

php-generator-liczb

Od czasu do czasu na forach internetowych widzę pytania dotyczące losowania liczb bez powtórzeń. Zamiast udzielać porad indywidualnie postanowiłem napisać ten krótki poradnik, który mam nadzieję pomoże w łatwym zrozumienia całego mechanizmu.

Jak zwykle jak to ja, tego typu poradniki staram się pisać kodem „łopatologicznym”, który mam nadzieje, jest łatwy do zrozumienia przez początkujących. Nie traćmy zatem czasu i bierzmy się do roboty.

Dlaczego rand() to zły pomnysł

Załóżmy, że chcemy wylosować sobie ze zbioru 50 liczb 4 takie, które na pewno będą unikalne. Na początku przychodzi Wam pewnie na myśl prosta funkcja rand:

<?php
$liczba1 = rand(1,50);
$liczba2 = rand(1,50);
$liczba3 = rand(1,50);
$liczba4 = rand(1,50);

Wydaje się, że zadziała? A no może zadziałać, ale nie musi. Każda z tych zmiennych może otrzymać inną liczbę, ale może też otrzymać taką samą. Z każdym razem funkcja rand() jest wywoływana od początku i wybiera liczby z zakresu od 1 do 50. Nie jest to poprawne rozwiązanie tego problemu.

Piszemy własne funkcje

W ramach tego ćwiczenia stworzymy sobie 2 funkcje. Jedna będzie generować nam zbiór liczb, a druga losować z niego liczby bez powtórzeń. Na początek napiszmy sobie funkcję, która stworzy nam tablicę wypełnioną danymi, w tym przypadku będą to liczby od 1 do 50:

<?php

function generuj_zbior($ilosc){

$ile=0; //deklarujemy na początku zero
$zbior_liczb=array(); //deklarujemy pustą tablice

//teraz pętla, która szybko wypełni nam tablicę danymi
while($ile<$ilosc){
$ile++;
$zbior_liczb[]=$ile;
}
return $zbior_liczb; //zwraca nam nasz zbiór
}

Ok, sprawdźmy czy działa, wywołajmy ją:

$zbior = generuj_zbior(50);
echo '<pre>';
print_r($zbior);
echo '</pre>';

Powinniście osiągnąć taki efekt:

Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 10
[10] => 11
[11] => 12
[12] => 13
[13] => 14
[14] => 15
[15] => 16
[16] => 17
[17] => 18
[18] => 19
[19] => 20
[20] => 21
[21] => 22
[22] => 23
[23] => 24
[24] => 25
[25] => 26
[26] => 27
[27] => 28
[28] => 29
[29] => 30
[30] => 31
[31] => 32
[32] => 33
[33] => 34
[34] => 35
[35] => 36
[36] => 37
[37] => 38
[38] => 39
[39] => 40
[40] => 41
[41] => 42
[42] => 43
[43] => 44
[44] => 45
[45] => 46
[46] => 47
[47] => 48
[48] => 49
[49] => 50
)

Pamiętajcie, że indeksy tablicy liczone są od zera. Dlatego finalne ostatni indeks ma nr 49 o wartości 50.

Ok, wiemy już, że nasza funkcja generująca zbiór danych działa. Teraz napiszemy funkcję, która z tych 50 liczb wylosuje nam te 4 unikalne:

function losuj_unikalne($zbior,$ile_wylosowac){

$wylosowane_liczby=array(); //jeszcze nic nie wylosowano, deklarujemy pustą tablice

//pętla załatwi sprawę z ilością losowanych liczb
for($i=0;$i<$ile_wylosowac;$i++){
$wylosowany_index = array_rand($zbior,1); //losujemy jakiś element tablicy z całego zbioru
$wylosowane_liczby[]=$zbior[$wylosowany_index]; //przypisuje wylosowany element tablicy do nowej tablicy
unset($zbior[$wylosowany_index]); //po wylosowaniu usuwamy ten element z tablicy by nie dopuścić do jego ponownego wylosowania
}
return $wylosowane_liczby; //zwraca unikalne wylosowane liczby
}

I to w zasadzie koniec. Teraz sprawdźmy naszą „losowarkę” na praktycznych danych. Poniżej całość kodu:

<?php
//autor: Marcin Romanowicz

function generuj_zbior($ilosc){

$ile=0; //deklarujemy na początku zero
$zbior_liczb=array(); //deklarujemy pustą tablice

//teraz pętla, która szybko wypełni nam tablicę danymi, w typ przypadku danymi
while($ile<$ilosc){
$ile++;
$zbior_liczb[]=$ile;
}
return $zbior_liczb; //zwraca nam nasz zbiór
}

function losuj_unikalne($zbior,$ile_wylosowac){

$wylosowane_liczby=array(); //jeszcze nic nie wylosowano, deklarujemy pustą tablice

//pętla załatwi sprawę z ilością losowanych liczb
for($i=0;$i<$ile_wylosowac;$i++){
$wylosowany_index = array_rand($zbior,1); //losujemy jakiś element tablicy z całego zbioru
$wylosowane_liczby[]=$zbior[$wylosowany_index]; //przypisuje wylosowany element tablicy do nowej tablicy
unset($zbior[$wylosowany_index]); //po wylosowaniu usuwamy ten element z tablicy by nie dopuścić do jego ponownego wylosowania
}
return $wylosowane_liczby; //zwraca unikalne wylosowane liczby
}

//no to generujemy
$zbior = generuj_zbior(50); //tworzy nam 50 elementów z których bęziemy losować
$losowanie = losuj_unikalne($zbior,4); //losuje nam 4 unikalne elementy

//wyświetlamy
echo '<pre>';
print_r($losowanie);
echo '</pre>';

?>

Ja osiągnąłem taki efekt. Na 99,9% u Was liczby będą inne niż u mnie. Grunt, by były ich dokładnie 4:

Array
(
[0] => 30
[1] => 31
[2] => 43
[3] => 16
)

Proste? Mam nadzieję. Podsumowując, by wylosować sobie dowolne liczby ze zbioru liczb wystarczy zmienić liczby podane w:

$zbior = generuj_zbior(50);
$losowanie = losuj_unikalne($zbior,4);

Udanego kodowania!


PS. jeśli masz konto na Facebooku, polub fanpage Konkretnego. Dzięki!




Tagi: , , , ,

Bądź miły! Uwielbiam wchodzić z Wami w dyskusję, proszę jednak, by krytyka była konstruktywna. Komentarz, który ma na celu obrażać mnie lub moich Czytelników może zostać usunięty. Tutaj każdy ma czuć się dobrze :)

Jestem także tutaj


YouTube - ostatni film z Filek.TV

YouTube - ostatni film z Konkretny.pl

Discord

Chcesz ze mną pograć?
Wbijaj na mój Discord

O blogu

Konkretny.pl to blog technologiczny, którego tematyka porusza kilka specjalistycznych dziedzin. Jednymi z najważniejszych są zagadnienia dotyczące technologii i Internetu, ale nie brakuje tutaj również typowych tekstów dotyczących finansów, marketingu, programowania, a nawet gier komputerowych. Życzę przyjemnej lektury :)


Social Media

 



© 2011-2024 Konkretny.pl. Wszelkie prawa zastrzeżone.

Wszystkie posty piszę w dobrej wierze. Nie odpowiadam jednak za wszelkie szkody, treść komentarzy oraz autentyczność informacji na stronie. Informuję, że publikowane pliki zostały sprawdzone programem antywirusowym w aktualnej wersji. Nie biorę jednak odpowiedzialności, jeśli coś się stanie.

| O mnie |   | Polityka Prywatności |   | Kontakt |