几件事:
- 而不是
Math.round()
,尝试Math.floor()
;在您的实现Math.round()
中,第一个元素(在索引 0 处)和最后一个元素比所有其他元素(.5/len vs. 1/len)的机会更少。请注意,在第一次迭代中,您输入arr.length - 1
元素arr.length
。
- 如果你有一个
required
变量,你也可以让它成为可选的,因为它默认为数组的长度:shuffle = (arr,
required=arr.length)
- 即使您只打乱了最后一个元素,您也会返回整个数组。考虑改为返回
arr[arr.length - required ..]
- 如果
required
不在范围内[0,arr.length]
怎么办?
将它们放在一起(并添加一些天赋):
shuffle = (arr, required=arr.length) ->
randInt = (n) -> Math.floor n * Math.random()
required = arr.length if required > arr.length
return arr[randInt(arr.length)] if required <= 1
for i in [arr.length - 1 .. arr.length - required]
index = randInt(i+1)
# Exchange the last unshuffled element with the
# selected element; reduces algorithm to O(n) time
[arr[index], arr[i]] = [arr[i], arr[index]]
# returns only the slice that we shuffled
arr[arr.length - required ..]
# Let's test how evenly distributed it really is
counter = [0,0,0,0,0,0]
permutations = ["1,2,3","1,3,2","2,1,3","2,3,1","3,2,1","3,1,2"]
for i in [1..12000]
x = shuffle([1,2,3])
counter[permutations.indexOf("#{x}")] += 1
alert counter