1. Álvéletlen számok
Néha a programozónak látszólag egyszerű feladatokkal kell szembenéznie: "válasszon ki egy véletlenszerű filmet egy bizonyos listáról", "válasszon egy lottó nyertest", "keverje össze a lejátszási listát, amikor a felhasználó megrázza az okostelefonját", "válasszon egy véletlen számot az üzenet titkosításához". , stb. A fejlesztő minden esetben feltesz egy logikus kérdést: hogyan lehet véletlen számot kapni?
Valójában egy igazán véletlen számot meglehetősen nehéz megtenni. Valójában ez olyan nehéz, hogy egyes számítógépekbe speciális matematikai koprocesszorokat építenek be, hogy olyan számokat állítsanak elő, amelyek megfelelnek a valódi véletlenszerűség minden követelményének.
A programozók saját megoldást találtak ki: pszeudovéletlen számok . Az álvéletlen számok egyfajta sorozat, amelynek számai véletlenszerűnek tűnnek. A gondos elemzés elvégzésével azonban a szakértő bizonyos mintákat találhat a sorozatban. Az ilyen számok nem alkalmasak titkos dokumentumok titkosítására, de a játékban a kockadobás szimulálására elegendőek.
Számos algoritmus létezik álvéletlen számsorozat generálására. Szinte mindegyik generálja a következő véletlenszámot az előző szám és néhány további segédszám alapján.
Például ez a program 1000
nem ismétlődő számokat jelenít meg:
public class Main
{
public static int a = 41;
public static int c = 11119;
public static int m = 11113;
public static int seed = 1;
public static int getNextRandom()
{
seed = (a * seed + c) % m;
return seed;
}
public static void main(String[] args)
{
for (int i = 0; i < 1000; i++)
{
System.out.println(getNextRandom());
}
}
}
Egyébként itt nem álvéletlen számokról beszélünk. Pszeudovéletlen számsorozatról beszélünk. Egyetlen számra nézve lehetetlen megmondani, hogy véletlenszerű-e vagy sem.
Valójában többféle módon lehet véletlen számot szerezni:
public static int getRandomNumber()
{
return 4; // Here's a random number (we got it by rolling a die)
}
2.Math.random()
Java-ban az Math
osztálynak van egy speciális metódusa, amely véletlen számot ad vissza. És ahogy sejtheti, a módszer neve random
. Általában a következőképpen néz ki ennek a módszernek a neve:
Math.random()
Ez a metódus nem vesz fel paramétereket, és pszeudovéletlen valós számot ad vissza a 0
-tól ig terjedő tartományban 1
. Maga az 1-es szám nem szerepel a tartományban.
Példa:
Kód | Konzol kimenet |
---|---|
|
|
De mi van, ha ez a módszer nem egészen az, amire szüksége van? Tegyük fel, hogy olyan programot akarunk írni, amely egy hatoldalú kocka dobását szimulálja. Hogyan kaphatunk véletlenszerű egész számokat az 1..6 tartományban a 0..1 tartományba eső valós számok helyett?
Valójában nagyon egyszerű.
Először is le kell képeznie a tartományt [0, 1)
a következőre [0, 6)
. Ehhez egyszerűen szorozza meg a visszaadott eredményt random()
-val 6
. Természetesen, hogy egész számokat kapjunk, fel kell kerekíteni:
Kód | Konzol kimenet |
---|---|
|
|
A tartomány egy getRandomDieNumber()
véletlenszerű egész számot ad vissza 0..5
. De ez nem lesz szám a készletben 1, 2, 3, 4, 5, 6
. Ez egy szám lesz a készletben 0, 1, 2, 3, 4, 5
.
Ha számokra van szüksége a készletben 1, 2, 3, 4, 5, 6
, akkor csak adjon hozzá egyet a véletlenszerű számokhoz:
Kód | Konzol kimenet |
---|---|
|
|
Ez most tökéletes!
3. Random
osztály
A Java-nak van egy speciális Random
osztálya, amely pszeudovéletlen számok sorozatát tartalmazza. Az osztályból több objektumot is létrehozhat Random
. Ezen objektumok mindegyike létrehoz egy saját pszeudovéletlen számsorozatot.
Ez egy szuper érdekes óra sok érdekes módszerrel. Kezdjük a legegyszerűbbel.
double nextDouble()
0.0
Ez a módszer egy véletlenszerű valós számot ad vissza a - tartományban 1.0
. Nagyon hasonlít a módszerhez Math.random()
. És nem csoda, hiszen a Math.random()
metódus egyszerűen meghívja a nextDouble()
metódust egy Random
objektumon.
float nextFloat()
Ez a metódus nagyon hasonlít a nextDouble()
metódushoz, de a visszaadott véletlen szám egy float
. 0.0
Szintén a - tartományba esik 1.0
. És mint mindig a Java-ban, a tartomány nem tartalmazza 1.0
magát a számot.
Random r = new Random();
float f = r.nextFloat();
int nextInt(int max)
Ez a metódus egy véletlenszerű egész számot ad vissza a tartományban [0, max)
. 0
benne van a kínálatban, de max
nem.
Más szóval, ha véletlen számot szeretne kapni a halmazban 1, 2, 3, 4, 5, 6
, akkor hozzá kell adnia egyet a visszaadott véletlen számhoz:
Random r = new Random();
int x = r.nextInt(6) + 1;
int nextInt()
Ez a módszer hasonló az előzőhöz, de nem igényel paramétereket. Tehát mi a visszatérési értékeinek tartománya? -tól -2 billion
-ig +2 billion
.
Nos, hogy pontos legyek, tól -2147483648
-ig +2147483647
.
long nextLong()
Ez a metódus hasonló a nextInt()
metódushoz, de a visszatérési érték valahol az s teljes lehetséges tartományába esik long
.
boolean nextBoolean()
Ez a metódus véletlenszerű boolean
értéket ad vissza: false
vagy true
. Ez nagyon kényelmes, ha véletlenszerű logikai értékek hosszú sorozatát kell beszereznie.
void nextBytes(byte[] data)
Ez a metódus nem ad vissza semmit (mivel a visszatérési típus void
). Ehelyett véletlenszerű értékekkel tölti fel az átadott tömböt. Ez nagyon hasznos, ha nagy, véletlenszerű adatokkal teli pufferre van szüksége.
double nextGaussian()
0.0
Ez a módszer egy véletlenszerű valós számot ad vissza a - tartományban 1.0
. A számok azonban nem egyenletesen oszlanak el ebben a tartományban. Ehelyett normál eloszlást követnek .
A tartomány közepéhez közeli értékek ( 0.5
) gyakrabban fordulnak elő, mint a tartomány végén lévő értékek.
Esetünkben az értékeloszlás csúcsa a0.5