随机数 生成时间要平均

安全维护

生成随机数组,在很多领域的开发中都会用到,例如游戏开发。随机数组生成的时间如果是固定的,那么执行效率就比较高;如果不固定,就可能会影响程序的运行速度。所以,在招聘考试中,一定会有生成随机数组的题目。

招聘题目:生成20个随机数字,该组数字中包含2组1~10之间的整数,即包含2个1、2个2,依此类推,但是每个数字的位置是随机的。

答案A:

int num[] = new int[20];

int index = 0; //数组下标

int ranNum; //随机数字

int time = 0; //数字已出现次数

Random r = new Random();

while(true){

ranNum = r.nextInt(9) + 1; //随机1~10之间的数字

//统计数字ranNum已出现次数

time = 0;

for(int i = 0;i < index;i++){

if(num[i] == ranNum){

time++;

}

}

//如果未出现2次

if(time != 2){

num[index] = ranNum;

index++; //继续赋值下一个

}

if(index == num.length){ //全部赋值

break;

}

}

答案B:

//生成2组1~10之间的规则数字

int num[] = new int[20];

for(int i = 0;i < num.length;i++){

num[i] = i / 2 + 1;

}

//随机打乱数字顺序

Random r = new Random();

int times = 30; //两两交换次数

int ranIndex; //随机下标

int temp; //交换变量

int cIndex; //当前下标

for(int i = 0;i < times;i++){

ranIndex = r.nextInt(20); //[0~20]之间的随机数,作为下标

//和下标i % 20交换

cIndex = i % 20;

if(cIndex != ranIndex){

temp = num[cIndex];

num[cIndex] = num[ranIndex];

num[ranIndex] = temp;

}

}

正确答案:B

答案分析

答案A使用的是自然思维,即随机生成一个1~10之间的数字,然后判断该数字是否已在数组中出现2次,如果未出现2次,则将该数字赋值到数组中,接着随机出现下一个数字。使用这种方式,虽然可以满足要求的功能,但是在程序的执行效率上很不稳定,每次随机过程所需时间的差异很大,甚至有可能卡死。如果程序中生成较多的随机数字,那么就不能用这种方法。

答案B采用的是一种变通的方法,先生成一组规则的数字,然后随机打乱改组数字的顺序。使用这种思路,程序的执行效率很稳定,而且实现起来比较简单。具体步骤如下:生成两组1~10之间的整数,按照1,1,2,2,……的顺序依次赋值到数组中,这样就得到一个规则的数组num。

接着使用两两交换的方式随机交换数组中数字的位置,生成一个随机数字,作为一个数组交换时的下标,然后和数组当前的下标进行交换,这样经过一定次数的交换以后,数组中的数字位置就变得随机了。每次交换消耗的时间基本固定,代码的执行效率很稳定,生成的速度也很高效。

扑克洗牌中的随机数组

高效生成随机数组,这种算法在实际的程序开发中大量被使用,特别是在游戏中被广泛使用,例如扑克游戏中的洗牌,网游中的随机掉装备等。下面,我们来看看在实际程序开发中是如何高效生成随机数组的。

代码的目的是要实现扑克游戏洗牌的功能,根据扑克牌的特点(每副牌包含54张不同的牌),将扑克牌中的每张牌依次对应编号成0~53之间的整数,那么一副牌就是一个包含0~53之间所有整数的数组,而洗牌就是将这样一个规则的数组变成一个随机数组。代码如下所示:

//生成一副牌,编号为0~53

int poker[] = new int[54];

for(int i = 0;i < poker.length;i++){

poker[i] = i;

}

//洗牌

Random r = new Random();

int times = 54; //两两交换次数

int ranIndex; //随机下标

int temp; //交换数字

int cIndex; //当前下标

for(int i = 0;i < times;i++){

ranIndex = r.nextInt(54); //[0~53]之间的随机数

//和下标i % 54交换

cIndex = i % 54;

if(cIndex != ranIndex){

temp = poker[cIndex];

poker[cIndex] = poker[ranIndex];

poker[ranIndex] = temp;

点评:在该代码中,先生成一个包含[0,53]之间所有整数的规则数组poker,然后再使用两两交换的方式对该数组中的元素交换54次。