Ce face std::uniform_int_distribution
std::uniform_int_distribution<T>(a, b) produce întregi între a și b, inclusiv ambele capete, fiecare cu aceeași șansă. Spre deosebire de rand() % n, distribuția este corectă pentru orice interval.
Distribuția nu generează singură numere: o apelezi cu un generator, dist(gen). Poți folosi aceeași distribuție de câte ori vrei. Cu un seed fix rezultatul este reproductibil pe același compilator, dar valorile concrete pot diferi între libc++, libstdc++ și MSVC.
Parametri
| Parametru | Descriere |
|---|---|
a, b |
Capetele intervalului, ambele incluse (a <= b). |
generator |
La apel: un generator, de exemplu std::mt19937. |
Ce returnează
La fiecare apel dist(gen), un întreg din [a, b].
Exemple
Exemplul 1: Zar și cod de verificare
#include <print>
#include <random>
int main() {
std::mt19937 gen(std::random_device{}());
std::uniform_int_distribution<int> zar(1, 6);
std::uniform_int_distribution<int> cod(100000, 999999);
std::println("Zar: {}", zar(gen));
std::println("Cod de verificare: {}", cod(gen));
}
Rezultat posibil (diferă la fiecare rulare)
Zar: 5
Cod de verificare: 472913
Exemplul 2: Frecvența fiecărei fețe (seed fix)
Din 60000 de aruncări, fiecare față apare în jur de 10000 de ori. Generatorul std::mt19937 cu seed fix produce aceleași numere pe orice compilator, dar modul în care o distribuție le transformă nu este fixat de standard. Rezultatul de mai jos este cel dat de libc++ (Clang); cu GCC sau MSVC, același seed poate da alte valori.
#include <array>
#include <print>
#include <random>
int main() {
std::mt19937 gen(1);
std::uniform_int_distribution<int> zar(1, 6);
std::array<int, 7> frecventa{};
for (int i = 0; i < 60000; ++i) {
++frecventa[zar(gen)];
}
for (int fata = 1; fata <= 6; ++fata) {
std::println("{}: {}", fata, frecventa[fata]);
}
}
Rezultat
1: 10008
2: 9957
3: 10021
4: 10036
5: 9959
6: 10019
Exemplul 3: Un element aleatoriu dintr-un vector
Intervalul este de la 0 la size() - 1, ambele incluse. Generatorul std::mt19937 cu seed fix produce aceleași numere pe orice compilator, dar modul în care o distribuție le transformă nu este fixat de standard. Rezultatul de mai jos este cel dat de libc++ (Clang); cu GCC sau MSVC, același seed poate da alte valori.
#include <print>
#include <random>
#include <string>
#include <vector>
int main() {
std::vector<std::string> citate{"Carpe diem", "Festina lente", "Veni, vidi, vici"};
std::mt19937 gen(7);
std::uniform_int_distribution<std::size_t> index(0, citate.size() - 1);
std::println("Citatul zilei: {}", citate[index(gen)]);
}
Rezultat
Citatul zilei: Carpe diem
Greșeli frecvente
- Scrii
uniform_int_distribution<int>(0, v.size()): capătul de sus este inclus, deci uneori primești un index în afara vectorului. - Folosești
uniform_int_distribution<char>: nu este permis de standard (doarshort,int,longși variantele lor). Generează unintși convertește-l.
Comenzi înrudite
std::mt19937: Generatorul Mersenne Twister: numere pseudo-aleatorii rapide și de calitate, reproductibile cu un seed fix.std::uniform_real_distribution: Produce numere cu virgulă aleatorii, distribuite uniform în intervalul [a, b).std::discrete_distribution: Alege aleatoriu un index 0, 1, 2… cu probabilități proporționale cu ponderile date.std::random_device: Sursă de numere aleatorii nedeterministe, oferită de sistem; folosită de obicei ca seed pentru std::mt19937.