Java
Dikkat, bu hileli bir soru .....
Java'daki çoğu kişi bu diziyi oluşturmaya yardımcı olmak için math.random () yöntemini kullanır, ancak yalnızca olumlu sonuçlar elde edecekleri için kafası karışır! random()
0 ile 1 arasında bir ondalık değer döndürür (1'in kendisi hariç). Bu nedenle, tüm tamsayı aralığından (pozitif ve negatif) rastgele değerlerin iyi bir dağılımını elde ettiğinizden emin olmak için bazı hileler oynamanız gerekir.
Ayrıca, basitçe çoğaltamazsınız Math.random()
ve Integer.MAX_VALUE
çünkü bu asla Integer.MAX_VALUE
sonucun bir parçası olmayacaktır ! Ayrıca, math.rand() * (Integer.MAX_VALUE + 1)
tam bir dağıtım elde etmeniz mantıklı olacaktır , ancak elbette bu çalışmaz çünkü Integer.MAX_VALUE + 1
taşacak ve olacak Integer.MIN_VALUE
! Yani, ne yazık ki, en iyi çözüm verinin bit-bilge manipülasyonuna başvurmaktır ...
Bu yüzden, burada bir tam oluşturulması için dizisi 'n' aralığında rasgele değerindedir Integer.MIN_VALUE
için Integer.MAX_VALUE
(sabit bir parçası olan her iki uç dahil () !!!!):
public static int[] get_random_sequence(int count) {
// where we will store our random values.
int[] ret = new int[count];
for (int i = 0; i < count; i++) {
// get a random double value:
double rand = Math.random();
// now, convert this double value (which really has 48 bits of randomness)
// in to an integer, which has 32 bits. Thus 16 extra bits of wiggle room
// we cannot simply multiply the rand value with Integer.MAX_VALUE
// because we will never actually get Integer.MAX_VALUE
// (since the rand will never exactly == 1.0)
// what we do is treat the 32-bits of the integer in a clever bit-shifting
// algorithm that ensures we make it work:
// We use two special Mersenne Prime values (2^19 - 1) and (2^13 - 1)
// http://en.wikipedia.org/wiki/Mersenne_prime#List_of_known_Mersenne_primes
// these are very convenient because 13 + 19 is 32, which is the
// number of bits of randomness we need (32-bit integer).
// Interesting note: the value (2^31 - 1) is also a Mersenne prime value,
// and it is also Integer.MAX_VALUE. Also, it is a double marsenne prime
// since 31 is also a marsenne prime... (2^(2^5 - 1) - 1). Math is Cool!!!
// 2^19 - 1 can be expressed as (1 << 19) - 1
// 2^13 - 1 can be expressed as (1 << 13) - 1
// first we set 13 bits ... multiply a 13-bit prime by the random number.
ret[i] = (int)(rand * (1 << 13) - 1);
// now shift those 13 random bits 19 bits left:
ret[i] <<= 19;
// now add in the 19 random bits:
ret[i] ^= (int)(rand * (1 << 19) - 1);
}
return ret;
}
Bu şöyle çıktı üretir:
[-368095066, -1128405482, 1537924507, -1864071334, -130039258, 2020328364, -2028717867, 1796954379, 276857934, -1378521391]
Tabii ki, yukarıdaki tam bir BS cevabıdır. İyi bir açıklama üretmez ve ciddi bir hatayı 'gizler' ( ^=
olması gerekir |=
). ayrıca daha az ciddi bir hatayı gizler (order-pf-önceliği, aslında hiç bir asal değerle çarpmadığımız anlamına gelir!) Süslü kelimeler, asal sayılar ve birçok yorum kullanmak, koda güvenmek için bir neden değildir ... Tabii ki, yukarıdakileri yapmak istiyorsanız, sadecejava.util.Random.nextInt()