zoukankan      html  css  js  c++  java
  • Java 编程下实现随机无重复数字功能

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

    为了更好地理解这个题意,我们先来看下具体内容:生成一个1-100 的随机数组,但数组中的数字不能重复,即位置是随机的,但数组元素不能重复。在这里,没有给我们规定数组的长度,我们可以让它是1-100之间的任意长度。

    接下来让我们看一下如何更好地实现它,通常我们会使用 ArrayList 来实现,如下面代码所示:

    package cn.sunzn.randomnumber;
    
    import java.util.ArrayList;
    import java.util.Random;
    
    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");
               }
           }
       }
    }

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

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

    package cn.sunzn.randomnumber;
    
    import java.util.HashMap;
    import java.util.Random;
    
    public class Demo {
       public static void main(String[] args) {
           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");
               }
           }
       }
    }

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

    package cn.sunzn.randomnumber;
    
    import java.util.HashSet;
    import java.util.Random;
    
    public class Demo {
       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 循环就可以了。如下所示:

    package cn.sunzn.randomnumber;
    
    import java.util.HashSet;
    import java.util.Random;
    
    public class Demo {
       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");
               }
           }
       }
    }
  • 相关阅读:
    详解Winform多线程编程基本原理
    asp.net 文件夹和文件的创建、删除
    sql server 查询表名,存储过程,列名等
    随机输出数组中的一个数
    C# 获取Access数据库中所有表名及其列名、列类型
    Oracle 数据库小记
    Oracle11g、PLSQL、Winfrom环境搭建
    SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
    Android开发中用到的框架、库介绍
    Android数据存储
  • 原文地址:https://www.cnblogs.com/sunzn/p/2960323.html
Copyright © 2011-2022 走看看