生成指定范圍內(nèi)的隨機(jī)數(shù)這個(gè)是最常用的技術(shù)之一,程序員希望通過(guò)隨機(jī)數(shù)的方式來(lái)處理眾多的業(yè)務(wù)邏輯,測(cè)試過(guò)程中也希望通過(guò)隨機(jī)數(shù)的方式生成包含大量數(shù)字的測(cè)試用例。
問(wèn)題往往類似于:
如何隨機(jī)生成 1~100 之間的隨機(jī)數(shù),取值包含邊界值 1 和 100。
或者是:
如何隨機(jī)生成隨機(jī)的3位整數(shù)?
等等……
以 java 語(yǔ)言為例,我們觀察其 random 對(duì)象的 nextint(int) 方法,發(fā)現(xiàn)這個(gè)方法將生成 0 ~ 參數(shù)之間隨機(jī)取值的整數(shù)。例如(假設(shè)先有 random rand = newrandom();,下同):
rand.nextint(100);
這行代碼將生成范圍0~100 之間的隨機(jī)數(shù),有趣的是,取值可能為 0 ,但不可能為 100。我們用中學(xué)數(shù)學(xué)課學(xué)習(xí)的區(qū)間表示法,表示為:[0, 100)。
那么如果要獲得區(qū)間 [1~100]的隨機(jī)數(shù),該怎么辦呢?稍微動(dòng)動(dòng)腦筋就可以想到:區(qū)間 [0, 100) 內(nèi)的整數(shù),實(shí)際上就是區(qū)間 [0, 99]。因?yàn)樽畲筮吔鐬?00,可惜不能等于100,因此最大可能產(chǎn)生的“整數(shù)”就是99。
既然rand.nextint(100) 獲得的值是區(qū)間 [0, 99],那么在這個(gè)區(qū)間左右各加 1,就得到了區(qū)間 [1, 100]。因此,代碼寫成:
rand.nextint(100)+ 1;
即可。運(yùn)行下面的代碼,將獲得 [1, 100] 的 10 個(gè)取值。
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 ); } } } |
同理,很容易知道如果要獲得隨機(jī)兩位整數(shù),代碼寫成:rand.nextint(90) + 10;
你一定很驚訝,為什么是這么寫出來(lái)的。其實(shí),在 nextint() 方法中作為參數(shù)的數(shù)字 90 表示:你希望生成的隨機(jī)數(shù)的所有取值的可能性的數(shù)量(在本命題中,兩位整數(shù)取值為 [10, 99],共90個(gè)數(shù));加好后面的數(shù)字 10 ,表示區(qū)間的最小取值。
你可以驗(yàn)證下,按照這樣理解,[1, 100] 的隨機(jī)數(shù),是不是應(yīng)該寫成rand.nextint(100) + 1 。千萬(wàn)不要把參數(shù) 100 理解為最大取值。只是區(qū)間 [1, 100] 正好從 1 開始,所以最大取值和取值可能性數(shù)量正好同為 100。
因此,
生成隨機(jī)三位數(shù)的代碼為:
rand.nextint(900)+ 100;
生成區(qū)間 [64,128] 中隨機(jī)值的代碼為:
rand.nextint(65)+ 64;
取值可能性的數(shù)量是如何計(jì)算出來(lái)的呢?當(dāng)然是 最大取值-最小取值+1 ,所以,有最終公式如下:
// for java
int randnumber =rand.nextint(max - min + 1) + min; // randnumber 將被賦值為一個(gè) min 和 max 范圍內(nèi)的隨機(jī)數(shù)
下面服務(wù)器之家小編分享一個(gè)網(wǎng)上常用的函數(shù)
函數(shù)一、要生成在[min,max]之間的隨機(jī)整數(shù)
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]之間的隨機(jī)數(shù),然后對(duì)(max-min+1)取模。
以生成[10,20]隨機(jī)數(shù)為例,首先生成0-20的隨機(jī)數(shù),然后對(duì)(20-10+1)取模得到[0-10]之間的隨機(jī)數(shù),然后加上min=10,最后生成的是10-20的隨機(jī)數(shù)
函數(shù)二、
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( "輸入產(chǎn)生的隨機(jī)數(shù)范圍,1到n,n=" ); int n= 0 ; try { n=integer.parseint( new bufferedreader( new inputstreamreader(system.in)).readline()); } catch (exception e){ system.out.println( "n必須為正整數(shù)" ); return ; } if (n< 1 ){ system.out.println( "n必須為正數(shù)" ); 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產(chǎn)生一個(gè)隨機(jī)數(shù)x,然后對(duì)這個(gè)之前產(chǎn)生的數(shù)據(jù)進(jìn)行遍歷,判斷是否存在有數(shù)等于這個(gè)新產(chǎn)生的隨機(jī)數(shù)的,如果有,立flag,
然后對(duì)之前的數(shù)據(jù)遍歷完畢之后,判斷flag是否立起來(lái),
如果是,就不添加這個(gè)隨機(jī)數(shù)進(jìn)數(shù)組,重新產(chǎn)生隨機(jī)數(shù)并收起flag,再重新遍歷已有的數(shù)據(jù)中是否已有這個(gè)隨機(jī)數(shù),
如果否,就添加,直到n個(gè)數(shù)據(jù)產(chǎn)生完畢。
最后輸出這個(gè)n個(gè)數(shù)據(jù)。
具體的運(yùn)行效果如下:
為了說(shuō)明這個(gè)程序是健壯的,讓電腦輸入n,其中這個(gè)n從1-20,可以觀察到,輸出的數(shù)組中沒(méi)有一個(gè)數(shù)是相同的,完成任務(wù)!
更多的數(shù)也是沒(méi)有問(wèn)題的,你設(shè)置n=二十萬(wàn),都沒(méi)有問(wèn)題,這里由于本猿猴的機(jī)器太渣,設(shè)置個(gè)n=33說(shuō)明效果。