JAVA实现随机无重复数字功能

来源:互联网 发布:ccs3.3是什么软件 编辑:程序博客网 时间:2024/04/29 09:31
本文给大家介绍如何在JAVA中实现随机无重复数字的功能。如果您是初学者的话,有必要看一看这篇文章,因为这个功能一般会在面试中遇到。包括我本人在招聘人员的时候也喜欢拿这个问题去问别人,主要看一看考虑问题的模式和基础知识如何。
  

  希望这篇文章能给初次接触的朋友一些帮助,因为我曾接触过一些朋友要么写不出来,要么使用很平铺的思维方式去实现它。

  一般有点开发经验的朋友都能实现这样的功能,只不过是效率上的问题。我们一般在面对这样的问题时,总会平铺直序的联想到,先生成一个数组,然后在一个循环中向数组中添加随机数字,在添加数字的过程中先查找一下数组中是否存在这个数字,如果不存在这个数字就直接添加到数组中;如果存在这个数字就不添加。我们一般都是这样考虑问题的,这样考虑也能实现功能,我刚才也说了,只不过是效率上的问题。

  为了更好地理解这个题意,我们先来看下具体内容:生成一个1-100的随机数组,但数组中的数字不能重复,即位置是随机的,但数组元素不能重复。

  在这里呢,没有给我们规定数组的长度,我们可以让它是1-100之间的任意长度。

 

  接下来让我们看一下几种实现方法并对这几种方法作个对比。

  通常我们会使用ArrayList或数组来实现,先来看下ArrayList实现过程,如下面代码所示:

复制代码
import java.util.ArrayList;import java.util.Random;/** * 使用ArrayList实现 * @Description:  * @File: Demo.java * @Package None * @Author Hanyongjian * @Company ANHEQINGYUAN * @Date 2012-10-18 下午06:16:55 * @Version V1.0 */public class Demo {    public static void main(String[] args) {        Object[] values = new Object[20];        Random random = new Random();        ArrayList<Integer> list = new ArrayList<Integer>();        for(int i = 0; i < values.length;i++){            int number = random.nextInt(100) + 1;                        if(!list.contains(number)){                list.add(number);            }        }                values = list.toArray();                // 遍历数组并打印数据        for(int i = 0;i < values.length;i++){            System.out.print(values[i] + "\t");                        if(( i + 1 ) % 10 == 0){                System.out.println("\n");            }        }    }}
复制代码

 

  使用数组实现的过程如下所示代码:

复制代码
import java.util.Random;/** * 使用数组实现 * @Description:  * @File: Demo4.java * @Package None * @Author Hanyonglu * @Date 2012-10-18 下午06:27:38 * @Version V1.0 */public class Demo4 {    public static void main(String[] args) {        int[] values = new int[20];        Random random = new Random();                for(int i = 0;i < values.length;i++){            int number = random.nextInt(100) + 1;                        for(int j = 0;j <= i;j++){                if(number != values[j]){                    values[i]=number;                }                                          }        }                // 遍历数组并打印数据        for(int i = 0;i < values.length;i++){            System.out.print(values[i] + "\t");                        if(( i + 1 ) % 10 == 0){                System.out.println("\n");            }        }    }}
复制代码

 

  上面这两个实现过程效率比较低的。因为在每次添加时都要去遍历一下当前列表中是否存在这个数字,时间复杂度是O(N^2)。我们可以这样思考一下:既然涉及到无重复,我们可以想一下HashSet和HashMap的功能。HashSet实现Set接口,Set在数学上的定义就是无重复,无次序的集合。而HashMap实现Map,也是不允许重复的Key。这样我们可以使用HashMap或HashSet来实现。

  在使用HashMap实现时,只需要将它的key转化成数组就Ok了,如下代码:

复制代码
import java.util.HashMap;import java.util.Iterator;import java.util.Random;import java.util.Map.Entry;/** * 使用HashMap实现 * @Description:  * @File: Demo.java * @Package None * @Author Hanyonglu * @Date 2012-10-18 下午06:12:50 * @Version V1.0 */public class Demo {    public static void main(String[] args) {        int n = 0;        Object[] values = new Object[20];                Random random = new Random();        HashMap<Object, Object> hashMap = new HashMap<Object, Object>();                // 生成随机数字并存入HashMap        for(int i = 0;i < values.length;i++){            int number = random.nextInt(100) + 1;            hashMap.put(number, i);        }                // 从HashMap导入数组        values = hashMap.keySet().toArray();                // 遍历数组并打印数据        for(int i = 0;i < values.length;i++){            System.out.print(values[i] + "\t");                        if(( i + 1 ) % 10 == 0){                System.out.println("\n");            }        }        //        Iterator iter = hashMap.entrySet().iterator();//        // 遍历HashMap//        while (iter.hasNext()) {//            Entry<Integer, Integer> entry = (Entry)iter.next();//            int key = entry.getKey();//            n++;//            //            System.out.print(key + "\t");//            //            if(n % 10 == 0){//                System.out.println("\n");//            }//        }    }}
复制代码

 

  由于HashSet和HashMap的关系太近了,HashSet在底层就是用HashMap来实现的,只不过没有Value的集合,只有一个Key的集合,所以也可使用HashSet来实现,如下代码:

复制代码
import java.util.HashSet;import java.util.Random;/** * 使用HashSet实现 * @Description:  * @File: Test.java * @Package None * @Author Hanyonglu * @Date 2012-10-18 下午06:11:41 * @Version V1.0 */public class Test {    public static void main(String[] args) {        Random random = new Random();        Object[] values = new Object[20];        HashSet<Integer> hashSet = new HashSet<Integer>();                // 生成随机数字并存入HashSet        for(int i = 0;i < values.length;i++){            int number = random.nextInt(100) + 1;            hashSet.add(number);        }                values = hashSet.toArray();                // 遍历数组并打印数据        for(int i = 0;i < values.length;i++){            System.out.print(values[i] + "\t");                        if(( i + 1 ) % 10 == 0){                System.out.println("\n");            }        }    }}
复制代码

 

  这样实现效率稍微好些。如果给我们限定了数组的长度,只需要变换下for循环,设置成whlie循环就可以了。如下所示:

复制代码
import java.util.HashSet;import java.util.Random;/** * 使用HashSet实现 * @Description:  * @File: Test.java * @Package None * @Author Hanyonglu * @Date 2012-10-18 下午05:11:41 * @Version V1.0 */public class Test {    public static void main(String[] args) {        Random random = new Random();        Object[] values = new Object[20];        HashSet<Integer> hashSet = new HashSet<Integer>();                // 生成随机数字并存入HashSet        while(hashSet.size() < values.length){            hashSet.add(random.nextInt(100) + 1);        }                values = hashSet.toArray();                // 遍历数组并打印数据        for(int i = 0;i < values.length;i++){            System.out.print(values[i] + "\t");                        if(( i + 1 ) % 10 == 0){                System.out.println("\n");            }        }    }}
复制代码

 

  我们可以把数组的长度设置成100,检验下运行效果,如下图所示:

 

  

 

  以上几种相比较而言,使用HashMap的效率是比较高的,其实是HashSet,再次是数组,最后是ArrayList。如果我们生成10000个数据将会发现,使用HashMap花费时间是:0.05s,HashSet是0.07s,数组是:0.20s,而ArrayList是0.25s。有兴趣的可以设置下时间查看一下。

 

  当然了,除了使用HashMap实现外,还有其它高效的方法。比如,我们可以把1-100这些数字存储在一个数组中,然后在for循环中随机产生两个下标,如果这两个下标不相等的话,可以交换数组中的元素,实现过程如下所示:

复制代码
import java.util.Random;/** * 随机调换位置实现 * @Description:  * @File: Demo4.java * @Package None * @Author Hanyonglu * @Date 2012-10-18 下午06:54:06 * @Version V1.0 */public class Demo4 {    public static void main(String[] args) {        int values[] = new int[100];           int temp1,temp2,temp3;           Random r = new Random();                   for(int i = 0;i < values.length;i++){            values[i] = i + 1;        }                //随机交换values.length次           for(int i = 0;i < values.length;i++){               temp1 = Math.abs(r.nextInt()) % (values.length-1); //随机产生一个位置               temp2 = Math.abs(r.nextInt()) % (values.length-1); //随机产生另一个位置                           if(temp1 != temp2){                temp3 = values[temp1];                   values[temp1] = values[temp2];                   values[temp2] = temp3;            }         }                   // 遍历数组并打印数据        for(int i = 0;i < 20;i++){            System.out.print(values[i] + "\t");                        if(( i + 1 ) % 10 == 0){                System.out.println("\n");            }        }    }}
复制代码

 

  这种方法也是比较高效的,如果生成10000个数据,那么它所用的时间是0.054s。

 

  在数组中利用坐标来实现的基础上可以变换更多相关的解决方法,具体地可以查阅相关资料。

 

  以上是关于在JAVA中实现随机无重复数字的功能,当然方法也不仅限于这么几种,还有其它的实现方法。希望能对接触不久的朋友有所帮助,也希望能够起到抛砖引玉的作用。

  

  示例下载:/Files/hanyonglu/JAVA/MyTestDemo.rar

 

  最后,希望转载的朋友能够尊重作者的劳动成果,加上转载地址:http://www.cnblogs.com/hanyonglu/archive/2012/10/18/2730007.html 谢谢。

 

  完毕。^_^

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 英雄联盟老是卡在安全扫描怎么办 英雄联盟活动送皮肤没送怎么办 电脑换完系统有些页面打不开怎么办 王卡助手交手机费页面打不开怎么办 在浏览器上打不开路由器页面怎么办 英雄联盟读条的时候自动关机怎么办 手机的位置信息开不了怎么办呢 滴滴车主接到乘客返回路程要怎么办 移动换话费积分是发什么短信怎么办 手机店积分换手机被贷款怎么办 心悦俱乐部礼包已过期是怎么办 心悦兑换的东西不是账号绑定怎么办 心悦会员绑定的手机号不用了怎么办 想在京东商城开个网店怎么办呢 京东买了东西收货了不想要了怎么办 京东转卖的商品有问题怎么办 如果衣服下架了然后有退货怎么办 想买二手车可没有懂车的人怎么办 买车的时候异地车牌回家怎么办 天猫下单显示下单人数太多券怎么办 英雄联盟进入游戏后无限崩溃怎么办 打开电视显示百度影棒打不开怎么办 家里路由器网速一会快一会慢怎么办 用快看影视下载电影网速太慢怎么办 苹果手机下载东西网速特别慢怎么办 网上买重庆时时彩输了很多钱怎么办 找不到自己在哪个平台借过钱怎么办 九游账号绑定手机之前绑定的怎么办 九游充过钱的游戏忘了游戏名怎么办 百度网盘密码忘了申诉不了怎么办 手机号被别人注册了百度账号怎么办 快手被盗找回时出来重置密码怎么办 魅族账号密码和密保都忘记了怎么办 vivo账号的密保问题忘了怎么办 oppo账号密保问题忘了怎么办 小米手机刷了机忘了账号密码怎么办 忘了小米账号的密码是多少怎么办 千牛账号在手机上被限制登录怎么办 违规的千牛账号被限制登录了怎么办 苹果id和锁屏密码忘记了怎么办 感应门的编程密码忘记了怎么办