[英]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.