You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Shuffle a collection, using the modern version of the// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle)_.shuffle=function(obj){varset=isArrayLike(obj) ? obj : _.values(obj);varlength=set.length;varshuffled=Array(length);for(varindex=0,rand;index<length;index++){rand=_.random(0,index);if(rand!==index)shuffled[index]=shuffled[rand];shuffled[rand]=set[index];}returnshuffled;};
原文
Splice
当时我是这样做的。每次 random 一个下标,看看这个元素有没有被选过,如果被选过了,继续 random,如果没有,将其标记,然后存入返回数组,直到所有元素都被标记了。后来经同事指导,每次选中后,可以直接从数组中删除,无需标记了,于是得到下面的代码。
Math.random
另一个为人津津乐道的方法是 "巧妙应用" JavaScript 中的 Math.random() 函数。
什么时候可以用这种方法乱序呢?"非正式" 场合,一些手写 DEMO 需要乱序的场合,这不失为一种 clever solution。
但是这种解法不但不正确,而且 sort 的复杂度,平均下来应该是 O(nlogn),跟我们接下来要说的正解还是有不少差距的。
Fisher-Yates Shuffle
数组乱序, 正确的解法应该是
Fisher-Yates Shuffle
,复杂度O(n)其实它的思想非常的简单,遍历数组元素,将其与之前的任意元素交换。因为遍历有从前向后往前两种方式,所以该算法也有两个版本的实现。
从后往前的版本:
underscore 中采用从前往后遍历元素的方式,实现如下:
将其解耦分离出来,如下:
随机性的数学归纳法证明
对 n 个数进行随机:
Read More:
The text was updated successfully, but these errors were encountered: