[英]Why use i + (int) (Math.random() * (n-i)) instead of (int) (Math.random() * n)?
我目前正在閱讀《計算機科學:一種跨學科的方法》這本書,其中包含用於對數組進行混排的代碼片段(在此示例中,數組包含一副紙牌)。 代碼如下:
int n = deck.length;
for (int i = 0; i < n; i++)
{
int r = i + (int) (Math.random() * (n-i));
String temp = deck[i];
deck[i] = deck[r];
deck[r] = temp;
}
我的問題是,為什么不首選更簡單的(int) (Math.random() * n)
? 是否比i + (int) (Math.random() * (ni))
隨機性小?
任何幫助表示贊賞!
它們給您不同的價值。
(int) (Math.random() * n)
為您提供一個值,范圍為0 <= r < n
(介於0
[包含]和n
[不含]之間)。
i + (int) (Math.random() * (ni))
為您提供i
<= r < n
范圍內的值(介於i
[包含]和n
[排除]之間)。
因此,例如,如果i
為10
,則您的“簡化”版本可以給您5
。 代碼中的版本不能。
想法是采用尚未選擇的隨機值。 如果您允許您的方案,那么某些元素可能永遠不會被改組,因此某些元素留在原地的機會太高了。
Math.Random()可以返回0.0到1.0之間的雙精度值。
https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#random()
因此,如果只執行(int)(Math.random()* n),則r的值可以大於n-1,而這將導致ArrayIndexoutofbound異常。
http://docs.oracle.com/javase/7/docs/api/java/lang/ArrayIndexOutOfBoundsException.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.