为什么使用 i + (int) (Math.random() * (n-i)) 而不是 (int) (Math.rand

  • 本文关键字:Math int n-i rand random java arrays math
  • 更新时间 :
  • 英文 :


我目前正在阅读《计算机科学:跨学科方法》一书,其中包含一个用于洗牌数组的代码片段(在本例中,数组包含一副纸牌)。代码如下:

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() * (n-i))随机性低吗?

任何帮助表示赞赏!

它们给你不同的值。

(int) (Math.random() * n)为您提供一个0 <= r < n范围内的值(介于 0 [包括] 和n [排除] 之间)。

i + (int) (Math.random() * (n-i))为您提供一个i <= r < n范围内的值(介于 i [包括] 和 n [排除] 之间)。

因此,例如,如果i10,您的"简化"版本可能会为您提供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

相关内容

最新更新