【问题标题】:Java Random number with no duplicate [duplicate]没有重复的Java随机数[重复]
【发布时间】:2013-06-20 02:59:03
【问题描述】:

我需要在 6 个不同的编辑文本中生成随机数。不幸的是,随机数重复了。我需要我设置的范围内的唯一数字。

        rndNumber = rndNumbers.nextInt(max);
        num1.setText(Integer.toString(rndNumber));


        rndNumber = rndNumbers.nextInt(max);
        num2.setText(Integer.toString(rndNumber));

        rndNumber = rndNumbers.nextInt(max);
        num3.setText(Integer.toString(rndNumber));

        rndNumber = rndNumbers.nextInt(max);
        num4.setText(Integer.toString(rndNumber));

        rndNumber = rndNumbers.nextInt(max);
        num5.setText(Integer.toString(rndNumber));

        rndNumber = rndNumbers.nextInt(max);
        num6.setText(Integer.toString(rndNumber));

【问题讨论】:

  • 我对此感到困惑:int nbr = 1; nbr < 2;。那不是只执行一次,就好像for 循环不存在一样?
  • 我在下面的回答解决了你提到的所有事情,并且完全按照你的要求做。

标签: java android


【解决方案1】:

包装随机数生成器以将结果存储在一个集合中。当你生成一个数字时,如果它存在于集合中,再做一次:

其他人对 for 循环的评论也是有效的...

伪代码:

class MyRandomNums {
    Set<Integer> usedNums;

    public int getRandom()
    {
        int num = random.nextInt();
        while(usedNums.contains(num)) {
            num = random.nextInt();
        }
        usedNums.add(num);
        return num;
    }

    public int reset()
    {
        usedNums.clear();
    }
}

【讨论】:

  • OP 应该知道这是一种不确定的方法(getRandom() 永远不会完成的可能性很小)。随着集合大小的增加和变满,执行时间会迅速增加。
  • @AntiEarth 是 99% 正确的 - 特别是如果您尝试使用范围(即 1 到 6 :一旦您选择了 6 个数字,您就可以保证无限循环,因为您已经用尽了范围)。 - 易于检测您是否有设定的范围。如果你不这样做会更难……为什么是 99% 而不是 100?恕我直言,这仍然是确定性的(否则请解释为什么不是 - 我更像是计算机专家而不是数学专家)
  • “[确定论指出]对于发生的一切都有条件,在这些条件下,不会发生其他任何事情。”考虑usedNums只有1个空位的情况,事件为产生的随机数个数(或运行时间)。结果(就时间而言)完全是概率性的(当然,假设是一个纯随机数生成器。我想它必须在我们的计算机中是确定性的);为填补最后一个空缺而生成的随机数在试验中不是恒定的(相同的前提条件,不同的帖子)。
  • @AntiEarth 如果您每次都为 RNG 播种相同的值,那将是确定性的,不是吗? (因为 RNG 将是一个应该生成相同序列的伪 RNG)
  • 是的,当然,但是如果您将先决条件限制为 usedNums 的状态或已经生成的数字,那么它是概率性的(就实际返回的方法而言,它们确实很重要;他们'是什么驱动运行时间)
【解决方案2】:

所有的 for 循环都循环一次。为什么:

for (int nbr = 1; nbr < 2; nbr++) {
    rndNumber = rndNumbers.nextInt(max);
    num1.setText(Integer.toString(rndNumber));
}

当你能做到时:

rndNumber = rndNumbers.nextInt(max);
num1.setText(Integer.toString(rndNumber));

?

【讨论】:

    【解决方案3】:
    int min = 0;
    int max = 100;
    List<Integer> randoms = new ArrayList<Integer>();
    for(int i = min; i <= max; i++) randoms.add(i);
    Collections.shuffle(randoms);
    

    那么你可以这样使用它:

    int randomNumber = randoms.remove(0);
    

    【讨论】:

    • 嗨!但是我将如何在 6 种不同的编辑文本中显示它?
    【解决方案4】:

    这是完成您提到的所有事情的一种方法:

    private static boolean arrayContainsInt(int array[], int val, int x) {
        for(int i = 0; i < x; i++) {
            if(array[i] == val) {
                return true;
            }
        }
        return false;
    }
    
    public static int[] randomNumbers(int count, int minInclusive, int maxNonInclusive) {
        int randoms[] = new int[count];
        Random rand = new Random();
        int impossibleValue = minInclusive - 1;
        for(int i = 0; i < randoms.length; i++) {
            randoms[i] = impossibleValue;
        }
        for(int x = 0; x < count; x++) {
            int thisTry = impossibleValue;
            while(thisTry == impossibleValue || arrayContainsInt(randoms, thisTry, x)) {
                thisTry = (int)(rand.nextFloat() * (float)(maxNonInclusive - minInclusive)) + minInclusive;
            }
            randoms[x] = thisTry;
        }
        return randoms;
    }
    

    如果您想了解速度,这里有一些统计数据:

    randomNumbers(1000, 0, 10000) ==> 16 毫秒

    (1000 个随机数。从 0->10,000 无重复)

    randomNumbers(10000, 0, 10000) ==> 207 毫秒

    (从0->10,000的每个数字以随机顺序生成)

    randomNumbers 方法提供了要生成的随机整数的数量、最小值(包括)和最大值(不包括),并在给定参数的情况下返回一个随机数组。

    注意:如果提供的count 参数大于maxNonInclusive - minInclusive 的值,那么它将无限循环,这仅仅是因为您无法提供比范围提供的更多的整数。

    此外,arrayContainsInt 会发送 x 参数作为数组中最大索引后的值以进行检查,因为只有 x 已填充数组的许多元素,因此检查其余元素是没有意义的。

    【讨论】:

      【解决方案5】:

      字母数字试试这个

      public String getRandomNum(int randomLength)
      {   
          return new BigInteger(130, random).toString(32).toUpperCase().substring(0, randomLength);
      }
      

      如果你只想要数字随机数试试这个

      public String getRandomNum(int randomLength)
      {
          int value = (int)(Math.random() * 9999);
          String format = "%1$0"+randomLength+"d";
          String randomNum = String.format(format, value);
          return randomNum;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-01
        • 2016-05-15
        • 1970-01-01
        • 2015-02-27
        • 2020-01-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多