最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java random.nextInt的坑及解決

 更新時(shí)間:2021年09月22日 16:42:21   作者:朝著希望前進(jìn)  
這篇文章主要介紹了java random.nextInt的坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

java random.nextInt的坑

下面的代碼

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

很簡(jiǎn)單的兩句代碼,需要注意兩點(diǎn)

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

api說(shuō)明:

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

第二個(gè):nextInt在數(shù)據(jù)量小的時(shí)候,重復(fù)概率比較高。比如現(xiàn)在有一個(gè)大小為6的list,我希望隨機(jī)顯示4條且不重復(fù)。正確的做法是每次得到隨機(jī)數(shù)后,移除下標(biāo)對(duì)于的對(duì)象。這樣即使random重復(fù)了也沒(méi)關(guān)系,因?yàn)橄聵?biāo)對(duì)應(yīng)數(shù)據(jù)移除后,同樣的下標(biāo)對(duì)應(yīng)的對(duì)象是不一樣的。

千萬(wàn)別像我之前的做法,遍歷list,然后隨機(jī)取到下標(biāo)后,再去重。這樣有時(shí)能得到4個(gè),有時(shí)得不到。比如下標(biāo)會(huì)出現(xiàn) 5,1,1,1,2,1.這樣的話,最終list只會(huì)有三個(gè)。

之前一直沒(méi)有懷疑是這段代碼的問(wèn)題,懷疑接口不穩(wěn)定或者是數(shù)據(jù)不完整之類(lèi)的。查日志還一直在看接口傳遞參數(shù)和返回參數(shù),結(jié)果是因?yàn)閷?duì)nextInt理解不深刻,在我印象中感覺(jué)randomInt是隨機(jī)數(shù)且不重復(fù)的,不過(guò)事實(shí)證明我想多了。

java random.nextInt()不隨機(jī)性

最近在研究算法,也寫(xiě)一些小程序,其中有一個(gè)是《算法導(dǎo)論》中的習(xí)題:描述RANDOM(a, b)過(guò)程的一種實(shí)現(xiàn),它只調(diào)用RANDOM(0, 1),作為a和b的函數(shù),你的程序的期望時(shí)間運(yùn)行時(shí)間是多少?

這個(gè)題在網(wǎng)上已經(jīng)有很多人給出了答案

我也自己寫(xiě)了一個(gè)算法,不過(guò)本文的主題不是針對(duì)這個(gè)問(wèn)題,而是RANDOM(0, 1)的實(shí)現(xiàn)方法。我剛開(kāi)始使用的是random.nextInt(0, 1)來(lái)取隨機(jī)的0和1,也測(cè)試了其“隨機(jī)性”,代碼如下:

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

用for循環(huán)10000萬(wàn)次,得到的0和1大致相當(dāng),可以得出獲得0和1的概率為0.5。但之后我就遇到了麻煩,我寫(xiě)了一個(gè)方法去實(shí)現(xiàn)RANDOM(a, b),例如RANDOM(0, 3),得到的結(jié)果是:

0有8335個(gè)

1有825個(gè)

2有42個(gè)

3有798個(gè)

我的算法是

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

我原本以為我寫(xiě)RANDOM(a, b)的算法錯(cuò)了。后來(lái)又寫(xiě)了一個(gè)算法,是網(wǎng)上很多人使用的算法,是將隨機(jī)產(chǎn)生的0和1拼成2進(jìn)制數(shù),然后轉(zhuǎn)換為十進(jìn)制數(shù),在一個(gè)區(qū)間內(nèi)在有效,超過(guò)這個(gè)區(qū)間則排除重取。

用這個(gè)算法得到的結(jié)果與第一種算法結(jié)果相同。我只好把第二種算法的二進(jìn)制數(shù)打印出來(lái)查找原因,發(fā)現(xiàn)一個(gè)問(wèn)題,就是0或1連續(xù)出現(xiàn)的概率要比0和1交叉出現(xiàn)的概率大,我想既然是隨機(jī)產(chǎn)生0和1,那這兩個(gè)生成的概率應(yīng)該相同才對(duì)。

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

驗(yàn)證如下

 //檢測(cè)Random.nextInt(2),連續(xù)獲取兩位0和1隨機(jī)數(shù)
 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;
  }
 }
 //獲取隨機(jī)數(shù)二進(jìn)制字符串
 public String getBoolean(){
  return new String(new Integer(randomBase0()).toString());
 }

使用for循環(huán)10000次,得到的計(jì)數(shù)結(jié)果如下:

"00"有4145個(gè)

"01"有928個(gè)

"10"有905個(gè)

"11"有4022個(gè)

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

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

以上面的方法為基礎(chǔ),用for循環(huán)獲取[0, 3]之間的整數(shù),得到的結(jié)果如下:

0有2525個(gè)

1有2551個(gè)

2有2433個(gè)

3有2491個(gè)

滿足要求,哈哈!

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解Java設(shè)計(jì)模式之單例模式

    詳解Java設(shè)計(jì)模式之單例模式

    單例模式是一種創(chuàng)建型設(shè)計(jì)模式,它的目的是確保一個(gè)類(lèi)只有一個(gè)實(shí)例,并提供一個(gè)全局訪問(wèn)點(diǎn)來(lái)訪問(wèn)該實(shí)例,在單例模式中,類(lèi)自身負(fù)責(zé)創(chuàng)建自己的唯一實(shí)例,并確保在系統(tǒng)中只有一個(gè)實(shí)例存在,本文詳細(xì)介紹了Java設(shè)計(jì)模式中的單例模式,感興趣的同學(xué)可以參考閱讀
    2023-05-05
  • 簡(jiǎn)單了解Java編程中拋出異常的方法

    簡(jiǎn)單了解Java編程中拋出異常的方法

    這篇文章主要介紹了Java編程中拋出異常的方法,是Java入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-11-11
  • 手把手教你寫(xiě)一個(gè)SpringBoot+gRPC服務(wù)

    手把手教你寫(xiě)一個(gè)SpringBoot+gRPC服務(wù)

    本文將在本地環(huán)境下搭建gRPC客戶(hù)端和服務(wù)端,并成功建立通訊發(fā)送消息的方式,從而幫助大家深入了解gRPC在Spring Boot項(xiàng)目中的應(yīng)用,有需要的小伙伴可以參考下
    2023-12-12
  • java繪制國(guó)際象棋與中國(guó)象棋棋盤(pán)

    java繪制國(guó)際象棋與中國(guó)象棋棋盤(pán)

    這篇文章主要為大家詳細(xì)介紹了java繪制國(guó)際象棋與中國(guó)象棋棋盤(pán),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • Java NIO框架Netty簡(jiǎn)單使用的示例

    Java NIO框架Netty簡(jiǎn)單使用的示例

    本篇文章主要介紹了Java NIO框架Netty簡(jiǎn)單使用的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • 一文總結(jié)Java獲取文件后綴名的所有方法

    一文總結(jié)Java獲取文件后綴名的所有方法

    Java是一種應(yīng)用廣泛的編程語(yǔ)言,可以通過(guò)多種方式來(lái)實(shí)現(xiàn)對(duì)文件的操作,如文件名后綴、文件擴(kuò)展名等,下面這篇文章主要給大家介紹了關(guān)于Java獲取文件后綴名的所有方法,需要的朋友可以參考下
    2023-05-05
  • 解讀.idea文件的使用及說(shuō)明

    解讀.idea文件的使用及說(shuō)明

    文章介紹了IntelliJ IDEA項(xiàng)目中的.idea文件夾及其作用,包括編譯配置、工作空間配置、項(xiàng)目標(biāo)識(shí)文件、編碼配置、jar包信息以及插件配置等,同時(shí),文章提醒在版本控制時(shí)應(yīng)排除.idea文件夾,以避免版本沖突
    2025-01-01
  • springcloud集成zookeeper的方法示例

    springcloud集成zookeeper的方法示例

    這篇文章主要介紹了springcloud集成zookeeper的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • Java實(shí)現(xiàn)讀取文章中重復(fù)出現(xiàn)的中文字符串

    Java實(shí)現(xiàn)讀取文章中重復(fù)出現(xiàn)的中文字符串

    本文主要介紹了Java實(shí)現(xiàn)讀取文章中重復(fù)出現(xiàn)的中文字符串的方法。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • java導(dǎo)出生成word的簡(jiǎn)單方法

    java導(dǎo)出生成word的簡(jiǎn)單方法

    這篇文章主要為大家詳細(xì)介紹了java導(dǎo)出生成word的簡(jiǎn)單方法,感興趣的朋友可以參考一下
    2016-03-03

最新評(píng)論

云和县| 黔江区| 怀安县| 千阳县| 方山县| 景洪市| 刚察县| 济源市| 新化县| 开江县| 平利县| 香港| 闽清县| 中牟县| 新昌县| 江西省| 临颍县| 溆浦县| 遵化市| 平陆县| 土默特左旗| 东乡县| 九江市| 西乌珠穆沁旗| 遵义县| 曲靖市| 罗山县| 略阳县| 乐业县| 林州市| 北宁市| 云龙县| 浮山县| 武功县| 旅游| 师宗县| 大埔区| 上林县| 九台市| 建宁县| 宁陵县|