Front-end web developer——[to be a better man]
[Mobile Version] | 文章字体大小Font Size文章字体大小:12px, 14px
11

Javascript多个不重复随机数

关于命题,我曾在google上搜索了很久,发现多数人对这个命题不感兴趣,当然部分同学说可以用离散什么的,哎呀,偶除了冒泡算法,可真不知道什么离散算法。笨人有笨办法,于是我写出了下面的一个代码:

var rmArrayElement=function(i,arr){return arr.slice(0,i).concat(arr.slice(i+1));};//返回移除了第i个数组的新数组
var rand=function(n){return Math.floor(Math.random()*(parseInt(n) || 1));};//返回小于n的整数随机数
var rands=function(n,c){//返回小于n的c个不重复的整数随机数
	var i=0,
	_reArr=[],//结果
	c=(typeof(parseInt(c))=="number" && c>1 && c<=n)?c:1,//随机数个数修正
	_tempRand=null,//所抓取的随机序号
	_tempArr=[];//临时数组
	for(i=0;i<n;i++){_tempArr=_tempArr.concat([i]);}//生成临时数组,此处有待改善:P
	for(i=0;i<c;i++){//循环不大于c次
		_tempRand=rand(_tempArr.length);//得到随机序号
		_reArr=_reArr.concat([_tempArr[_tempRand]]);//从临时数组中抓1个随机数
		_tempArr=rmArrayElement(_tempRand,_tempArr);//在临时数组中删除已抓取的数组
	}
	return _reArr;//返回最终结果
};

这个代码的特点:
循环次数不超n+c次,可用于生成多个不重复的随机数。
缺点:n可能很大。。。。。。
建议用于100以内的随机数生成。例如,有50个广告,每次随机显示3个。
也可以用于把序号进行随机打散,如rands(20,20):
[9,19,17,14,0,1,15,4,6,8,11,12,18,13,2,3,16,7,10,5]

这个代码经过变化,还可以变成取得区间内的随机数的函数,有兴趣的同学可以去试一试。不过上面的代码有一个缺憾,就是n这个数可能会很大,多数人找随机数是找9999999以内的随机数。但这么大的数,随便取十多个也来也不怕会有重复了 :P

另外,把生成临时数组部分进行改善,也会有很大的效率提升哦,只是我还没想到更好的办法,或者完全不用这个方法。
还有,这个东西很神奇:

Array.prototype.riffle = function(){
    var sf = function(){ return 0.5 - Math.random(); }
    this.sort(sf).sort(sf);
}

代码从这里找到的,我还百思不得其解,为什么这样的洗牌会让数组乱序,真的太神奇了,如果可以这样,那就简单多了,只要洗一次牌,然后取前n个数组不就可解决前面的问题了吗!

唉,我发觉自己对javascript真的越来越无知了 :cry: 。请各位多多指教,THX!

2 条评论

  • At 2009.09.18 03:37, ryan said:

    这个是很简单的洗牌算法
    try google shuffle

    • At 2009.09.20 02:38, GOVO said:

      是啊,我对算法不怎么在行

      (Required)
      (Required, will not be published)