生成指定范圍內的隨機數這個是最常用的技術之一,程序員希望通過隨機數的方式來處理眾多的業務邏輯,測試過程中也希望通過隨機數的方式生成包含大量數字的測試用例。
問題往往類似于:
如何隨機生成 1~100 之間的隨機數,取值包含邊界值 1 和 100。
或者是:
如何隨機生成隨機的3位整數?
等等……
以 java 語言為例,我們觀察其 random 對象的 nextint(int) 方法,發現這個方法將生成 0 ~ 參數之間隨機取值的整數。例如(假設先有 random rand = newrandom();,下同):
rand.nextint(100);
這行代碼將生成范圍0~100 之間的隨機數,有趣的是,取值可能為 0 ,但不可能為 100。我們用中學數學課學習的區間表示法,表示為:[0, 100)。
那么如果要獲得區間 [1~100]的隨機數,該怎么辦呢?稍微動動腦筋就可以想到:區間 [0, 100) 內的整數,實際上就是區間 [0, 99]。因為最大邊界為100,可惜不能等于100,因此最大可能產生的“整數”就是99。
既然rand.nextint(100) 獲得的值是區間 [0, 99],那么在這個區間左右各加 1,就得到了區間 [1, 100]。因此,代碼寫成:
rand.nextint(100)+ 1;
即可。運行下面的代碼,將獲得 [1, 100] 的 10 個取值。
1
2
3
4
5
6
7
8
9
|
import java.util.random; public class test { public static void main(string[] args){ random rand = new random(); for ( int i= 0 ; i< 10 ; i++) { system.out.println(rand.nextint( 100 ) + 1 ); } } } |
同理,很容易知道如果要獲得隨機兩位整數,代碼寫成:rand.nextint(90) + 10;
你一定很驚訝,為什么是這么寫出來的。其實,在 nextint() 方法中作為參數的數字 90 表示:你希望生成的隨機數的所有取值的可能性的數量(在本命題中,兩位整數取值為 [10, 99],共90個數);加好后面的數字 10 ,表示區間的最小取值。
你可以驗證下,按照這樣理解,[1, 100] 的隨機數,是不是應該寫成rand.nextint(100) + 1 。千萬不要把參數 100 理解為最大取值。只是區間 [1, 100] 正好從 1 開始,所以最大取值和取值可能性數量正好同為 100。
因此,
生成隨機三位數的代碼為:
rand.nextint(900)+ 100;
生成區間 [64,128] 中隨機值的代碼為:
rand.nextint(65)+ 64;
取值可能性的數量是如何計算出來的呢?當然是 最大取值-最小取值+1 ,所以,有最終公式如下:
// for java
int randnumber =rand.nextint(max - min + 1) + min; // randnumber 將被賦值為一個 min 和 max 范圍內的隨機數
下面服務器之家小編分享一個網上常用的函數
函數一、要生成在[min,max]之間的隨機整數
1
2
3
4
5
6
7
8
9
10
11
12
|
import java.util.random; public class randomtest { public static void main(string[] args) { int max= 20 ; int min= 10 ; random random = new random(); int s = random.nextint(max)%(max-min+ 1 ) + min; system.out.println(s); } } |
random.nextint(max)表示生成[0,max]之間的隨機數,然后對(max-min+1)取模。
以生成[10,20]隨機數為例,首先生成0-20的隨機數,然后對(20-10+1)取模得到[0-10]之間的隨機數,然后加上min=10,最后生成的是10-20的隨機數
函數二、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
import java.util.*; import java.io.*; public class random_different { public static void main(string[] args) throws ioexception{ system.out.print( "輸入產生的隨機數范圍,1到n,n=" ); int n= 0 ; try { n=integer.parseint( new bufferedreader( new inputstreamreader(system.in)).readline()); } catch (exception e){ system.out.println( "n必須為正整數" ); return ; } if (n< 1 ){ system.out.println( "n必須為正數" ); return ; } int randarr[]= new int [n]; int i= 0 ; while (i<n){ int rand=( new random().nextint(n)+ 1 ); boolean israndexist= false ; for ( int j= 0 ;j<randarr.length;j++){ if (randarr[j]==rand){ israndexist= true ; break ; } } if (israndexist== false ){ randarr[i]=rand; i++; } } system.out.println(arrays.tostring(randarr)); } } |
首先在1~n產生一個隨機數x,然后對這個之前產生的數據進行遍歷,判斷是否存在有數等于這個新產生的隨機數的,如果有,立flag,
然后對之前的數據遍歷完畢之后,判斷flag是否立起來,
如果是,就不添加這個隨機數進數組,重新產生隨機數并收起flag,再重新遍歷已有的數據中是否已有這個隨機數,
如果否,就添加,直到n個數據產生完畢。
最后輸出這個n個數據。
具體的運行效果如下:
為了說明這個程序是健壯的,讓電腦輸入n,其中這個n從1-20,可以觀察到,輸出的數組中沒有一個數是相同的,完成任務!
更多的數也是沒有問題的,你設置n=二十萬,都沒有問題,這里由于本猿猴的機器太渣,設置個n=33說明效果。