sofish / learn-js

老婆想学 js 这件事就是一个政治任务
143 stars 9 forks source link

第七天:Fisher–Yates Shuffle #9

Open sofish opened 8 years ago

sofish commented 8 years ago

最近有时差,昨天的任务今天来写 👎 。

昨天写了前天的任务「如何分组」。大家都会需要用到「洗牌」,而关于如何洗有多种算法,其中有一个简洁高效的算法就是 Fisher-Yates Shuffle https://bost.ocks.org/mike/shuffle/ ( 文章和演示都非常棒 )。

在「如何分组」里我写了一个思路,里面有一种重要的点是不断从原来的数组踢除数值,这会导致数组本身重排,而这是 Fisher-Yates 要避免的问题,他采用的是交换的方法来避免重排,如下中文注释。

function shuffle(array) {
  var m = array.length, t, i;

  // While there remain elements to shuffle…
  while (m) {

    // Pick a remaining element…
    i = Math.floor(Math.random() * m--);

    // And swap it with the current element.
    t = array[m];  // 缓存当前的第 m 位
    array[m] = array[i]; // 随机 m 之前某位放进 m
    array[i] = t; // 第随机位换成 m 位的值(后续还会被取到)
  }

  return array;
}

感慨,算法总是逼死我们这些文科生。

lishengzxc commented 8 years ago

splice()是有点慢的,有次遇到做动画的时候,需要频繁去从数组里面删除一项,发现很慢(就是因为慢导致了问题,如果在前面一次splice还没完成立马又splice就出问题了),就用object模仿一个数组,直接用delete就好了