要生成在[min,max]之間的隨機整數,有人寫了下面的代碼:
random.nextInt(max)%(max-min+1) + min;
認爲這樣就可以得到[min,max]之間的隨機整數。完整代碼:
public int[] intArray1(int arrayLength,int min,int max){
int[] a = new int[arrayLength];
Random random = new Random();
for (int i = 0; i < arrayLength; i++) {
a[i] = random.nextInt(max) % (max - min + 1) + min;
System.out.print(a[i]+" ");
}
return a;
}
看起來沒有問題,其實沒問題的前提是min非負。
當arrayLength=10,min=-5,max=4的時候,運行上面的代碼3次,得到3個結果:
-2 -4 -2 -4 -3 -3 -5 -3 -3 -2
-4 -3 -4 -4 -4 -5 -5 -5 -4 -4
-5 -2 -2 -5 -2 -3 -2 -2 -3 -2
觀察結果可知,數據分佈不均勻,大於0的數偏少,正常的話應該是-5至0數的數目與0至5數的個數大致相同。
分析代碼:random.nextInt(max)%(max) + min
1、random.nextInt(max)是生成[0,max)之間的數(不包括max)。這裏應當換爲random.nextInt(max+1)纔對;
2、%(max-min+1)的目的是讓數落在[0,max-min+1
)之間;
3、最後的+
min是做平移;
第1、第2步可以合併成random.nextInt(max-min+1),省去了取餘運算。
數據分佈不均勻的原因在於當min爲負數的時候,random.nextInt(max)生成隨機數的範圍是[0,max),區間長度max-0比max-min短:
當數據做平移的時候,數據都移到了前面,後面沒有數據,所以數據分佈不均勻。
觀察前面的結果發現,
正確的代碼:
public int[] intArray2(int arrayLength,int min,int max){
int[] a = new int[arrayLength];
Random random = new Random(); //使用當前時間即System.currentTimeMillis()作爲發生器的種子
int len = max-min;
int bound = len+1;
for(int i=0;i<arrayLength;i++){
a[i] = random.nextInt(bound) + min;
}
return a;
}
運行上面的代碼3次,得到3個結果:
-4 -5 3 -5 1 -4 -4 -2 2 -1
-2 -5 -5 3 -1 -5 -4 1 -5 -3
-3 -4 -1 3 -2 1 -2 0 4 2