方案1:1531 毫秒
一般的思路是先创建一个1-3000的数组,每一次取出一个,然后让这个数组减少一个,
取一个,减少一个,这样就可以做到永不重复了。
var count=3000;
var original=new Array;//原始数组

//给原始数组original赋值
for (var i=0;i<count;i++){
original[i]=i+1;
}

var d1=new Date().getTime();
for (i=0;i<count;i++){
var index=Math.floor(Math.random()*original.length); //随机取一个位置
document.write(index+" , "); //打印
original.splice(index,1)
}
var d2=new Date().getTime();

document.write("<br />运算耗时"+(d2-d1));

方案2:297毫秒
但是方案1采用了slice方法,此方法重新生成数组,会大量占用内存和cpu运算,
效率很低,所以改良一下,从原始数组取出一个数,
然后让原始数组的这个位置赋值为null
这样下一次取数的时候判断如果为null就不取,直到不为null为止。
经过测试,可以显著提高效率
var count=3000;
var original=new Array;//原始数组

//给原始数组original赋值
for (var i=0;i<count;i++){
original[i]=i+1;
}

var d1=new Date().getTime();
for (var num,i=0;i<count;i++){
do{
num=Math.floor(Math.random()*count);
}while(original[num]==null);
document.write(original[num]+" , ");
original[num]=null;
}
var d2=new Date().getTime();

document.write("<br />运算耗时"+(d2-d1));

方案3:234毫秒
换一个思路,如果把原始数组origin打散,然后再依次打印,
这样也可以做到随机永不重复,而且效率更高,
因为方案2运行到越后面,原始数组为null的频率就越高,运算的次数就越多
var count=3000;
var original=new Array;//原始数组

//给原始数组original赋值
for (var i=0;i<count;i++){
original[i]=i+1;
}


var d1=new Date().getTime();
original.sort(function(){ return 0.5 - Math.random(); });
for (var i=0;i<count;i++){
document.write(original[i]+" , ");
}
var d2=new Date().getTime();

document.write("<br />运算耗时"+(d2-d1));

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>随机不重复</title>
<script type="text/javascript">var count=3000;
var original=[];//原始数组
var temp;
var d1=new Date().getTime();
for(var i=0;i<count;){
  temp = parseInt(Math.random()*count+1);
if(original[temp]==undefined){
 original[temp] = temp;
 document.write(temp+" , ");
 i++;
 }
}
var d2=new Date().getTime();
document.write("<br />运算耗时"+(d2-d1));
</script>
</head>
<body>
</body>
</html>

 

JavaScript的Math对象提供了random()方法,可以获取一个[0,1)的随机数

利用这个方法,取一个随机数容易

但要是取一个随机并且不重复的数,就需要绕点弯子

试着更换一下思路

获取随机数并不一定需要随机取得一个值,并前后判断是否重复

可以首先创建一个范围,并以该范围所有的值创建一个数组

将数组的排序随机

那么从该数组中按线性获取的值,不也就是随机不定的吗

且由于只是重新排列了数组,数组中永远不会出现重复的值

只需利用Array的sort()方法和Math.random()方法就可以实现获取随机不重复的功能

简单讲一下Array的sort()方法:

sort()用于数组,如果不传入参数,那么它会对数组的每一项调用toString()方法,再对每一个字符串进行比较排序(按照首字符的编码大小排序)

若传入参数,会按照参数的正负情况对每两个进行该方法的数组项排序。

无参的方法调用在升降排序number类型数据时并不好用,所以一般给sort()方法传入一个“比较”函数,以此为number类型的数组项升降排序

利用该方法的排序特性,随机这种排序就可以达到随机打乱数组的效果

以下是该方法的实现:

 

[javascript] view plain copy
 
  1. function sjsz(num){  
  2.     var ary = [];                   //创建一个空数组用来保存随机数组  
  3.     for(var i=0; i<num; i++){            //按照正常排序填充数组  
  4.         ary[i] = i+1;  
  5.     }  
  6.     ary.sort(function(){  
  7.         return 0.5-Math.random();       //返回随机正负值  
  8.     });  
  9.     return ary;                 //返回数组  
  10. }  

给函数 sjsz 传入一个 num 参数已确定随机数组范围(0 - num 之间)

之后函数会返回一个不重复随机数组成的数组