高效生成随机数组——已发《电脑报》

原创 2010年07月06日 11:04:00

求职不怕考

pcw-chendx@vip.sina.com

与编程相关的招聘,都会准备很多考题,一不小心考生就在考题上栽了跟头,特别是没有多少工作经验的应届毕业生,往往回答得过于理论化,很难令考官满意。为此,我们特意推出本系列,通过对真实考题的分析让大家在回答考题时有更多的实用性,让考官满意,顺利找到工作。

高效生成随机数组

爪哇米工作室 陈跃峰

算法是程序的灵魂,所以在面试中基本都要考核应聘者的算法能力。算法的种类有很多,每种算法在实现时都有独立的方式,本文将介绍的生成随机数组的算法只是其中的一种。生成随机数组,即固定的一组数组但是数字位置随机的数组,是一种反映应聘者基础数字逻辑掌握程度的基础算法。下面以一个简单的例子来介绍高效生成随机数组的算法实现。

招聘题目:生成20个随机数字,该组数字中包含21-10之间的整数,即包含2122,依次类推,但是每个数字的位置是随机的。

答案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

//生成21-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之间的整数,按照1122,……这样的顺序依次赋值到数组中,这样得到的是一个规则的数组num,这个数组中包含所有需要的数字,即21-10之间的数字,但是数字的顺序是规则的。接着使用两两交换的方式随机交换数组中数字的位置,交换的方法是生成一个0到数组长度(不包含)的随机数字,作为一个数组交换时的下标,然后和数组当前的下标,即第一次下标为0,第二次下标为1,的元素进行交换,这样经过一定次数的交换以后,数组中的数字位置就变得随机了。而每次的交换消耗的时间是基本固定的,所以实现起来整个算法的执行效率很稳定,生成的速度也很高效。

实际应用

高效生成随机数组这种算法在实际的程序开发中也大量的进行使用。例如在棋牌类的游戏开发中,例如斗地主、双扣等,在每次游戏开始时,都需要打乱扑克牌的顺序,然后再将打乱以后的扑克牌依次发放给每个游戏玩家。而这种打乱扑克牌顺序的算法通常就被称作洗牌算法。

从程序开发的角度看洗牌算法,实际上生成的就是一组规则的随机数字,例如对于一副扑克牌来说,在程序中如果需要代表一副扑克牌,根据扑克牌的特点(每幅牌包含54张不同的牌)则只需要为每张牌进行编号即可,例如将扑克牌中的每张牌依次对应编号成0-53之间的整数,那么一副牌就是一个包含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次,这个次数可以根据需要进行调整,从而得到了一个符合逻辑要求的数组poker。而对于玩家来说,poker这个数组就是一副被洗过的扑克牌,可以以此为基础进行游戏后续的逻辑的开发了。

高效生成随机数组

与编程相关的招聘,都会准备很多考题,一不小心考生就在考题上栽了跟头,特别是没有多少工作经验的应届毕业生,往往回答得过于理论化,很难令考官满意。为此,我们特意推出本系列,通过对真实考题的分析让大家在回答...
  • taobao755624068
  • taobao755624068
  • 2010年08月16日 17:56
  • 994

C实例---生成随机数组

问题描述:在写排序算法时,很希望得到一个大一点的排序数据,且是随机数据。如果直接输入的话很浪费时间,下面的这个小程序有效的解决了这样的一个问题。 代码:#include #include #in...
  • huazhen1234
  • huazhen1234
  • 2016年12月27日 15:50
  • 425

python生成随机数组

研究排序问题的时候常常需要生成随机数组来验证自己排序算法的正确性和性能,今天把python生成随机数组的方法稍作总结,以备以后查看使用。...
  • healthy_coder
  • healthy_coder
  • 2016年01月12日 11:09
  • 15898

随机生成数组

数组的随机产生以及数组的输出 在调用的时候需要注意返回时需要带入变量名如: genArray(arr,range);import java.util.Random;//放在开头,跟Scanner ...
  • young_so_nice
  • young_so_nice
  • 2015年09月10日 12:58
  • 804

通过随机函数生成一个随机的数组

通过随机函数生成一个随机的数组
  • YinJianxiang
  • YinJianxiang
  • 2017年03月20日 18:11
  • 1111

Java学习 产生一个随机数组的两种方法

import java.util.Random;// 导入包 public class RandomTest { public static void main(String[] args) ...
  • xuli99999
  • xuli99999
  • 2013年04月17日 17:26
  • 4194

生成数组的随机排列

1. 假设有一个数组,里面有10个元素 inta[10]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9}。请写一个算法,得到a数组的一个随机排列。要求时间复杂度尽量小,可以使用rando...
  • yangkaikwill
  • yangkaikwill
  • 2015年09月10日 16:16
  • 779

产生随机数组的方法

问题描述: 现要求产生 0~n-1 范围内的 m 个随机整数的有序列表,且不允许重复,m 考虑到 n 的值可能很大,而通常 C/C++ 提供的随机数产生器所能返回的随机数在 [0,RAND_MA...
  • aafengyuan
  • aafengyuan
  • 2013年03月15日 11:22
  • 3296

js-随机产生一个由10个元素组成的数组

一.随机产生一个由10个元素组成的一个数组。 第一步:创建一个随机函数; 第二步:定义一个空数组; 第三步:for循环遍历,将随机的每一个数添加在数组里面。 上面的这一种方法,随机产生的10个元素...
  • Jerry_Zhangyuan
  • Jerry_Zhangyuan
  • 2016年10月22日 17:40
  • 3718

生成随机数组的两种方式

package com.wansha; import java.util.Random; public class aTest { public static void main(String[...
  • xpsharp
  • xpsharp
  • 2011年09月13日 16:29
  • 1542
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:高效生成随机数组——已发《电脑报》
举报原因:
原因补充:

(最多只允许输入30个字)