生成0到1000之间的唯一随机数

时间:2012-05-21 21:35:19

标签: java random

  

可能重复:
  Generating Unique Random Numbers in Java

如何生成0到1000之间的随机数,并继续将生成的0到1000之间的唯一随机数传递给特定方法。因此,为此我生成了0到1000之间的数字,并在List中插入0到1000之间的唯一随机数,以便我们可以比较我们生成的随机数是否已经存在于列表中。如果它存在则再次生成它。但不知怎的,我相信下面的代码有时会失败。

public class Testing4 {
    private static List<Integer> randomNumber;
    private static Random r = new Random();
    private static int rand;
    private static int endRange = 1000;

    public static void main(String args[]) throws IOException {

        randomNumber = new ArrayList<Integer>();

        for (int i = 1; i<= endRange; i++) {
            rand = r.nextInt(endRange);

            if(randomNumber.contains(rand)) {
                rand = r.nextInt(endRange);
            } else {
                randomNumber.add(rand);
            }

        // Pass the unique random number between 0 and 1000 to this method      
                randomNumberMethod(rand);

        }
    }
}

4 个答案:

答案 0 :(得分:3)

您实际上是以随机顺序生成0-1000之间的数字列表。您可以通过以下方式更有效地实现这一目标:

public class Testing4 {
    private static List<Integer> randomNumber;
    private static int endRange = 1000;

    public static void main(String args[]) throws IOException {

        randomNumber = new ArrayList<Integer>(endRange);

        for (int i = 0; i<= endRange; i++) {                
            randomNumber.add(i);
        }

        Collections.shuffle(randomNumber);

        for (int i = 0; i<= endRange; i++) {                
            // Pass the unique random number between 0 and 1000 to this method      
            randomNumberMethod(randomNumber.get(i));
        }
    }
}

考虑一下到999时会发生什么 - 每次绕循环,你将有999的机会'猜测'剩余的可用数字。

答案 1 :(得分:2)

要生成介于0和1000之间的唯一数字列表,请执行以下操作:

  • 创建一个包含0到1000之间所有数字的列表
  • 使用Collections.shuffle()
  • 对列表进行随机播放
  • 从列表中获取您需要的第一个数字。

有些情况下需要更复杂的算法,但是如果您需要选择的可能数字和项目数量的范围都在1000的数量级,您实际上可能只需要第一个 n 来自随机洗牌的所有可能性的数字。

如果你想做你建议的事情,那么:

  • 使用while循环,因为另一张海报建议
  • 使用Set而非列表来存储已选择的值。

但是,这会变得效率低下,因为要选择的项目数量往往会增加可能项目的数量(例如,如果您从可能的1000中选择10个数字,那么它就可以了;你可以选择900中的900,这将变得效率低下,因为每次在找到之前未选择的数字之前需要拒绝越来越多的数字。

答案 2 :(得分:1)

从代码检查中,我在这个方法中看不到任何会阻止它进行工作的东西,效率非常低。

首先,检查数字是否是您看过randomNumber.contains(rand)的数字会花费越来越多的时间,因为每次执行数字时产生的数字越多,您就必须将它与每个数字进行比较列表中的数字,直到您找到匹配的或您已尝试列表中的每个数字。更好的方法是使用HashSet而不是列表,这应该使每个成员资格测试花费相同的时间,无论你放入多少东西。

可以通过注意到您可能提出错误的问题来进行第二次,更重要的优化。您是否尝试生成唯一的随机数,或者您是否尝试以随机顺序生成介于1和endRange之间的每个数字?如果你想要每个数字(或者甚至是它们中的一个非常重要的部分),只需将1到1000之间的每个数字放入一个列表然后使用{{3}将它们洗牌,这将会更快。 }。所以你的代码将是:

java.util.List<Integer> nums = new java.util.ArrayList<Integer>(1001);
for (int i = 0; i <= 1000; i++)
{
   nums.add(new Integer(i));
}
java.util.Collections.shuffle(nums);

答案 3 :(得分:0)

如果连续生成ArrayList中已存在的2个数字,则代码将失败。它将使用第二个数字,无论它是否重复。 if语句应该是while循环(继续尝试直到它生成一个唯一的循环)。

public class Testing4 {
    private static HashSet<Integer> randomNumber;
    private static Random r = new Random();
    private static int rand;
    private static int endRange = 1000;

    public static void main(String args[]) throws IOException {

        randomNumber = new HashSet<Integer>();

        for (int i = 1; i<= endRange; i++) {    
            do
            {
               rand = r.nextInt(endRange);
            }
            while(randomNumber.contains(rand));

            randomNumber.add(rand);

            // Pass the unique random number between 0 and 1000 to this method      
            randomNumberMethod(rand);

        }
    }
}

编辑:根据评论,您应该使用do / while和散列数据结构而不是arraylist来加速重复查找。最终的编辑在上面的代码中。