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

时间:2017-01-09 04:00:11

标签: java arrays math

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

make

我的问题是,为什么更简单的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)

更随机

任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:0)

他们给你不同的价值观。

(int) (Math.random() * n)为您提供0 <= r < n范围内的值(0 [包含]和n [不包含]之间的值)。

i + (int) (Math.random() * (n-i))为您提供 i <= r < n范围内的值( i [包含]之间的值n [独家])。

例如,如果i10,则您的&#34;简化&#34;版本可以给你5。代码中的版本不能。

答案 1 :(得分:-1)

这个想法是采取一个尚未被选中的随机值。如果您允许使用您的方案,那么某些元素可能永远不会被洗牌,因此某些元素保留在原位的可能性太大。

答案 2 :(得分:-2)

Math.Random()可以返回介于0.0和1.0之间的double值。

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