设为首页 加入收藏

WWW-4444KK-COM【首页★新址】WWW-4444KK-COM_日韩★WWW-4444KK-COM

当前位置: 主页 > www-W4444KK-com > Javascript/Ajax >

javascript使数组内的值的索引随机化和创建随机数组

时间:2012-11-27 02:01来源:网络整理 作者:管理员 点击:
今天在QW交流群里看到有同学讨论使数组随机化的问题,其中给出的算法很不错,让我想起了之前自己实现过的不怎么“漂亮”的方法。想想我们有时候在繁忙的写业务代码时只是为了实现其功能,并未花太大心思去思考是否有更好的实现方法。
就这个数组问题(随即排序一个数组里的值,返回一个新数组)来说,我以前的实现方法是这样的:
双击代码全选
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function randArr(arr) {        var ret = [],        obj = {},        i = arr.length,        l = i,        n;                       while (--i >= 0) {            n = Math.floor( Math.random() * l );            if (obj[n] === void 0) {                ret[ret.length] = obj[n] = arr[n];            } else {                i++;            }        }        return ret;    }
  上 面的代码会工作,但并不是一个好的算法,它打算执行“原数组的长度”次循环,每一次循环会随机取一个原数组中的索引,然后判断该索引是否已被取过,如果没 有则把该索引的值放入新数组中,如果取过则把自减键 i 自增1(目的是重复该次循环直到取到另一个未取过的索引)。这样的方法的性能是很看人品的,原因相信看到这种思路的同学都已明白了。
现在给出群里那位同学的算法:
双击代码全选
1 2 3 4 5 6 7 8 9 10 11 12 function randArr(arr) {        var ret = [],        i = arr.length,        n;        arr = arr.slice(0);                       while (--i >= 0) {            n = Math.floor( Math.random() * i);            ret[ret.length] = arr.splice(n, 1)[0];        }        return ret;    }
  这是一个相当巧妙的算法,在每次循环中取一个随机的索引后,并把它的值从数组中删除,这样,如果后面依然随机取到这个索引,这个索引就已经不再是上一次取到的值了,而且随机数的取值范围会根据数组的长度的减小而减小,这样就能一次性循环一定的次数而得到理想的结果。
还看到了一个改进版的,是考虑到了对数组的删除操作而导致的些许性能问题,运用了JK大的洗牌算法,即把每一次删除操作改为了位置替换操作(取到的该索引的值和当前自减键 i 对应的值进行互换),这样对整个数组的影响是最小的,还是放代码吧:
双击代码全选
1 2 3 4 5 6 7 8 9 10 11 12 13 function randArr(arr) {        var ret = [],        i = arr.length,        n;        arr = arr.slice(0);                       while (--i >= 0) {            n = Math.floor( Math.random() * i);            ret[ret.length] = arr[n];            arr[n] = arr[i];        }        return ret;    }
  最后给出一个“创建值为min~max间的随机数组”的方法,算法原理同上面的差不多:
双击代码全选
1 2 3 4 5 6 7 8 9 10 11 12 13 function makeRandArr(min, max) {        var ret = [],        obj = {},        n;                       for (; max >= min; max--) {            n = Math.ceil( Math.random() * (max - min) ) + min;            ret[ret.length] = obj[n] || n;            obj[n] = obj[max] || max;        }                       return ret;    }

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
用户名: 验证码: 点击我更换图片
栏目列表
推荐内容