中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何解決java中random.nextInt的坑

發布時間:2021-09-24 11:28:39 來源:億速云 閱讀:310 作者:小新 欄目:開發技術

小編給大家分享一下如何解決java中random.nextInt的坑,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

java random.nextInt的坑

下面的代碼

Random random = new Random();
Integer code = random.nextInt(len);

很簡單的兩句代碼,需要注意兩點

第一:nextInt的取值是[0,n) ,不包括n。如果是隨機list,直接傳list的size,不用擔心下標越界。

api說明:

Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive)

第二個:nextInt在數據量小的時候,重復概率比較高。比如現在有一個大小為6的list,我希望隨機顯示4條且不重復。正確的做法是每次得到隨機數后,移除下標對于的對象。這樣即使random重復了也沒關系,因為下標對應數據移除后,同樣的下標對應的對象是不一樣的。

千萬別像我之前的做法,遍歷list,然后隨機取到下標后,再去重。這樣有時能得到4個,有時得不到。比如下標會出現 5,1,1,1,2,1.這樣的話,最終list只會有三個。

之前一直沒有懷疑是這段代碼的問題,懷疑接口不穩定或者是數據不完整之類的。查日志還一直在看接口傳遞參數和返回參數,結果是因為對nextInt理解不深刻,在我印象中感覺randomInt是隨機數且不重復的,不過事實證明我想多了。

java random.nextInt()不隨機性

最近在研究算法,也寫一些小程序,其中有一個是《算法導論》中的習題:描述RANDOM(a, b)過程的一種實現,它只調用RANDOM(0, 1),作為a和b的函數,你的程序的期望時間運行時間是多少?

這個題在網上已經有很多人給出了答案

我也自己寫了一個算法,不過本文的主題不是針對這個問題,而是RANDOM(0, 1)的實現方法。我剛開始使用的是random.nextInt(0, 1)來取隨機的0和1,也測試了其“隨機性”,代碼如下:

 //用Random.nextInt(2)獲取0,1隨機數
 //獲取概率均為0.5,但不隨機
 public int randomBase0() {
  Random r = new Random();
  return r.nextInt(2);
 }

用for循環10000萬次,得到的0和1大致相當,可以得出獲得0和1的概率為0.5。但之后我就遇到了麻煩,我寫了一個方法去實現RANDOM(a, b),例如RANDOM(0, 3),得到的結果是:

0有8335個

1有825個

2有42個

3有798個

我的算法是

將b-a+1擴展到2的最小冪級數,如果是個數為5,則取8(2^3),如果為16,則取16(2^4),然后用分治算法獲取a與b之間的數,其中需要將大于b的數去除掉,重新獲取。

我原本以為我寫RANDOM(a, b)的算法錯了。后來又寫了一個算法,是網上很多人使用的算法,是將隨機產生的0和1拼成2進制數,然后轉換為十進制數,在一個區間內在有效,超過這個區間則排除重取。

用這個算法得到的結果與第一種算法結果相同。我只好把第二種算法的二進制數打印出來查找原因,發現一個問題,就是0或1連續出現的概率要比0和1交叉出現的概率大,我想既然是隨機產生0和1,那這兩個生成的概率應該相同才對。

因此我得出結論,使用Random.nextInt(0, 1)獲取隨機數的概率并不隨機,原因是其生成連續相同0或1的概率與生成交叉0和1的概率不等,并且前者大于后者,盡管單獨獲取0和1的個數比相當,換句話說,用這種方法獲取0和1的事件不獨立。

驗證如下

 //檢測Random.nextInt(2),連續獲取兩位0和1隨機數
 public int randomBaseS() {
  String s = new String(new StringBuffer().append(getBoolean()).append(getBoolean()));
  
  if("00".equals(s)){
   return 0;
  }else if("01".equals(s)){
   return 1;
  }else if("10".equals(s)){
   return 2;
  }else{
   return 3;
  }
 }
 //獲取隨機數二進制字符串
 public String getBoolean(){
  return new String(new Integer(randomBase0()).toString());
 }

使用for循環10000次,得到的計數結果如下:

"00"有4145個

"01"有928個

"10"有905個

"11"有4022個

那哪種算法能滿足要求呢?如下:

 //用Math.random()獲取0,1隨機數
 //獲取概率均為0.5,且隨機
 public int randomBase() {
  return Math.random()>0.5?1:0;
 }

以上面的方法為基礎,用for循環獲取[0, 3]之間的整數,得到的結果如下:

0有2525個

1有2551個

2有2433個

3有2491個

以上是“如何解決java中random.nextInt的坑”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

西乌| 石嘴山市| 左贡县| 临西县| 湾仔区| 江川县| 安庆市| 洛川县| 巨野县| 宜君县| 松江区| 安化县| 石屏县| 巴彦淖尔市| 日照市| 泸州市| 华亭县| 韩城市| 宜川县| 和田市| 山阳县| 和政县| 巨鹿县| 宣武区| 循化| 丹东市| 宜兴市| 贵溪市| 阜宁县| 邵武市| 四平市| 甘德县| 阳东县| 克东县| 太仆寺旗| 太白县| 固镇县| 平山县| 武汉市| 家居| 邓州市|