随机化方法的问题

时间:2014-01-29 00:39:41

标签: java algorithm sorting methods random

我的方法无法正常工作。 该方法应该随机地将一组数字从1到20排序(每个数字 必须只出现一次)。 我的问题是,当我运行程序时,一些数字会重复几次。 代码如下:

public static int randomize(int index) {

    //This array will hold the 20 numbers.
    int[] randomIndex = new int[20];

    Random ranNum = new Random();

    for (int x = 0; x<20; x++) {
        int temp;

        //The number is generated randomly and saved in temp.
        temp = ranNum.nextInt(20);

        //This loop skips the first index.
        if (x != 0){

            /*Here, the loop is supposed to compare a generated number with
            the previous one*/
            for (int y = 1; y<=x; y++) {


                while(temp == randomIndex[x-y] ) {

                    /*If the while loop finds that temp variable matches any previous                          
                    number it will generate another random number for it until it finds
                    no matches.*/
                    temp = ranNum.nextInt(20);

                }  
            }
        }

    /*Once no match has been found for temp, the number is assigned to an index, 
    and the loop is executed with a x variable increment.
    randomIndex[x] = temp;

    }
   //Finally the array with the set of random numbers is sent to the main function.
   return randomIndex[index];

  }

我得到了以下输出:

19, 19, 5, 16, 6, 2, 18, 1, 15, 1, 5, 19, 11, 4, 18, 0, 5, 18, 10.

所以现在我不知道该怎么做。 :C

4 个答案:

答案 0 :(得分:1)

使用Random.nextInt()时,无法保证生成的数字是唯一的。 您应首先生成1到20之间的数字,然后将数字洗牌。现在问题改为“如何随机改变数字?”

也许您可以参考JDK Collections.shuffle()的实现。

洗牌的算法很简单:

  1. 选择数组中的第一个元素,并将其与随机位置的数字交换。
  2. 重复步骤1直到最后一个元素。

答案 1 :(得分:0)

您可以通过使用以下内容来避免它:

   final Random random = new Random();


    final HashSet<Integer> integers = new HashSet<>();

    while(integers.size() < 20) {
        integers.add(random.nextInt(20));
    }

    System.out.println(integers);

答案 2 :(得分:0)

看起来你试图通过拒绝来生成随机数 - 也就是说,通过将每个随机数与之前接受的所有数字进行比较,然后重新生成新的随机数,直到找到与所有数字不同的数字。它们。

正如其他人所提到的那样,从1到20生成数字会更有效,并且随机置换将其洗牌。但是,如果正确实施,您的方法最终应该有效。

随机shuffle实现可能如下所示:

for(int i=0; i<20; i++) {  // index goes from 0..19
  randomIndex[i] = i + 1;  // value goes from 1..20
}

for(int i=0; i<20; i++) {
  int j = i + ranNum.nextInt(20 - i);  // choose random j from i <= j < 20
  int temp = randomIndex[i];           // swap elements i and j
  randomIndex[i] = randimIndex[j];
  randomIndex[j] = temp;
}

这是您发布的代码生成重复项的两个原因。首先,当您拒绝候选随机数并重新生成新的随机数时,您需要将其与所有现有数字进行比较,从头开始重新启动内部(y)循环。您现有的代码不会这样做。

其次,我相信new Random()构造函数每次调用时都会生成不同的种子。如果是这样,您的randomize()函数每次都会生成一个完全不同的随机列表,并从中返回所选索引。无论如何,返回整个数组更有意义。

答案 3 :(得分:0)

我编辑了生成数组的函数,从1到20:

public static int[] randomize() {

    int[] randomIndex = new int[20];

    Random ranNum = new Random();
    boolean isAlreadyIn;
    boolean isZero;
    int x = 0;

    while (x < 20) {
        isAlreadyIn = false;
        isZero = false;
        int temp;
        temp = ranNum.nextInt(21);
        for(int i = 0; i < randomIndex.length; i++){
            if(temp == 0)
                isZero = true;
            if(temp == randomIndex[i])
                isAlreadyIn = true;
        }
        if (!isZero && !isAlreadyIn){
            randomIndex[x] = temp;
            x++;
        }
    }

   return randomIndex;
}

希望它会有所帮助。