Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych. Autor artykułu: mgr Jerzy Wałaszek, wersja1.0 |
©2010 mgr
Jerzy Wałaszek |
Pomoce:
W wielu zastosowaniach musimy wygenerować kilka liczb pseudolosowych, tak aby żadna z nich się nie powtarzała. Na przykład przy symulacji gry w karty żaden z graczy nie powinien dostać 5 asów w rozdaniu. Przy losowaniu Totka Lotka wylosowane liczby również nie mogą się powtarzać. Problem ten rozwiązujemy prosto wykorzystując operacje na tablicach.
Pierwsza metoda jest następująca:
Chcemy wygenerować n z m różnych liczb pseudolosowych,
gdzie n ≤ m (zakres musi obejmować
co najmniej n liczb, w przeciwnym razie nie da się uzyskać n
liczb różnych). Wykorzystujemy tablicę n elementową, w
której będziemy umieszczali wygenerowane liczby.
Pierwszą liczbę pseudolosową generujemy swobodnie i wstawiamy ją do tablicy - musimy zapamiętywać, ile liczb zawiera tablica. Każdą następną liczbę pseudolosową porównujemy z liczbami wstawionymi do tablicy. Jeśli jej tam nie będzie, to dopisujemy tę liczbę do tablicy i operację powtarzamy dotąd, aż tablica się zapełni.
Sposób ten jest szczególnie efektywny, gdy n jest małe, a m duże.
Wejście:
n - ilość liczb
pseudolosowych do wygenerowania
Wyjście:
T[ ] - n elementowa tablica z liczbami pseudolosowymi
Dane pomocnicze:
i - indeksy
elementów
licznik - zlicza wygenerowane
liczby pseudolosowe
p - liczba pseudolosowa
Krok 1: | licznik ← 0 | ; zerujemy licznik wygenerowanych liczb pseudolosowych |
Krok 2: | p ← liczba pseudolosowa | ; generujemy liczbę pseudolosową |
Krok 3: | i ← 0 | |
Krok 4: | Jeśli i = licznik, to idź do kroku 8 | |
Krok 5: | Jeśli T[i] = p, to idź do kroku 2 | ; sprawdzamy, czy w tablicy już jest liczba p. Jeśli tak, generujemy nową liczbę p |
Krok 6: | i ← i + 1 | ; adresujemy kolejny element tablicy |
Krok 7: | Idź do kroku 4 | ; kontynuujemy przeglądanie tablicy |
Krok 8: | T[licznik] ← p | ; dopisujemy liczbę p do tablicy |
Krok 9: | licznik ← licznik + 1 | ; zwiększamy licznik |
Krok 10: | Jeśli licznik < n, idź do kroku 2 | ; jeśli nie wygenerowaliśmy jeszcze n liczb, kontynuujemy pętlę |
Krok 11: | Zakończ |
// Generacja liczb pseudolosowych bez powtórzeń // (C)2011 I LO w Tarnowie //------------------------ #include <iostream> #include <cstdlib> #include <time.h> using namespace std; const int N = 20; // określa ilość liczb do wygenerowania int main() { int T[N], p, i, licznik; bool t; srand(time(NULL)); // inicjujemy ziarno generatora pseudolosowego // generujemy N różnych liczb pseudolosowych w zakresie od 1 do 80 licznik = 0; do { p = 1 + rand() % 80; t = true; for(i = 0; i < licznik; i++) if(T[i] == p) { t = false; break; } if(t) T[licznik++] = p; } while(licznik < N); // wyświetlamy wygenerowane liczby for(i = 0; i < N; i++) cout << T[i] << " "; cout << endl << endl; return 0; } |
Druga metoda jest następująca:
Chcemy wygenerować n z m różnych liczb pseudolosowych.
Tworzymy tablicę m elementową i umieszczamy w niej wszystkie liczby
pseudolosowe, które chcemy otrzymywać, Następnie w pętli wykonywanej 10 × m razy
losujemy dwa indeksy tej tablicy i zamieniamy miejscami elementy wskazywane
przez te indeksy. Gdy pętla zakończy swoje działanie, zawartość tablicy będzie
potasowana - elementy przestaną być uporządkowane. Teraz wystarczy odczytać z
tej tablicy
n pierwszych elementów.
Sposób ten jest szczególnie efektywny, gdy n jest porównywalne z m, a m niezbyt duże.
Wejście:
m - ilość elementów tablicy.
T[ ] - tablica m elementowa do
pomieszania. Elementy mają indeksy od 0 do m-1.
Wyjście:
T[ ] - tablica z pomieszanymi elementami
Dane pomocnicze:
i1,i2
- indeksy elementów
i - zlicza obiegi pętli
x - zmienna pomocnicza do zamiany
elementów T[ ].
Krok 1: | i ← 10 × m | |
Krok 2: | Jeśli i = 0, to zakończ | |
Krok 3: | i1 ← liczba pseudolosowa od 0 do m - 1 | ; losujemy dwa indeksy elementów |
Krok 4: | i2 ← liczba pseudolosowa od 0 do m - 1 | |
Krok 5: | x ← T[i1] | ; elementy zamieniamy miejscami |
Krok 6: | T[i1] ← T[i2] | |
Krok 7: | T[i2] ← x | |
Krok 8: | i ← i - 1 | |
Krok 8: | Idź do kroku 2 |
// Generacja liczb pseudolosowych bez powtórzeń // (C)2011 I LO w Tarnowie //------------------------ #include <iostream> #include <cstdlib> #include <time.h> using namespace std; const int N = 20; // określa ilość liczb do wygenerowania const int M = 80; // określa rozmiar tablicy int main() { int T[M], i, i1, i2, x; srand(time(NULL)); // inicjujemy ziarno generatora pseudolosowego // Tablicę wypełniamy liczbami od 1 do M for(i = 0; i < M; i++) T[i] = i + 1; // tablicę mieszamy for(i = 10 * M; i > 0; i--) { i1 = rand() % M; i2 = rand() % M; x = T[i1]; T[i1] = T[i2]; T[i2] = x; } // wyświetlamy początkowe N liczb z tablicy for(i = 0; i < N; i++) cout << T[i] << " "; cout << endl << endl; return 0; } |
Dla ambitnych: wykorzystując programy z lekcji zaprojektuj symulację Toto Lotka.
Użytkownik typuje 10 swoich liczb. Następnie program wykonuje kolejne losowania
(np. 10 losowań), sprawdza, czy wylosowano liczby
użytkownika i wypisuje wyniki tego sprawdzenia - np. ilość liczb trafionych oraz
wartości liczb trafionych w losowaniu. Zastanów się nad sposobem uzyskania i
wyświetlania tych wyników.
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe