Java数组和随机数

时间:2014-03-14 08:39:43

标签: java arrays

我正在尝试生成一组随机数。每个数组条目都有一个0到31之间的数字。我试图让代码生成一个随机数,然后检查数组中是否存在该数字。如果是,则会生成一个新的随机数,并从头开始检查。

我以为我用以下代码怀疑它:

 public class HelloWorld{

     public static void main(String []args){
        int[] randArray = new int[10];
        boolean firstNumber = true;
        int randNum = 0;

        for (int j=0; j < randArray.length; j++) {

            if(firstNumber) {
                randNum = (int)(Math.random() * 31 + 1);
                randArray[j] = randNum;
                firstNumber = false;
            } else {
                for (int k=0; k < randArray.length;) {
                    randNum = (int)(Math.random() * 31 + 1);
                    if(randArray[k] == randNum) {
                        k=0;
                    } else { 
                       k++;   
                    }
                }
                randArray[j] = randNum;
                System.out.println(j);
            }
        }

        System.out.println("-------");

        for(int i=0; i < randArray.length; i++) {

            System.out.println(randArray[i]);

        }
    }
}

但这就是打印出来的内容:

  

1 2 3 4 5 6 7 8 9   ------- 25 17 19 20 24 4 26 30 6 24

如您所见,24重复两次。如果我再次运行代码,您可以看到存储的重复数字。

从逻辑上讲,我无法弄清楚为什么会这样做。它可能很简单,但我看不到它。

我是编程新手,这是我认为我会测试我的知识的。

7 个答案:

答案 0 :(得分:3)

您生成唯一随机数的方法是错误的,因为当您到达数组中的最后一个数字n时,您只有1 / n几率生成所需的特定数字。而且由于您使用的是随机数,可能会在成功生成整个数组之前等待很长时间。此外,生成阵列的时间非常难以预测。

更好的方法是生成一个序列递增的数组,然后对这个数组进行洗牌。这样,您可以保证在O(n)中生成数组,并在O(n)中对数组进行洗牌。

int arraySize=32;
int[] myArray= new int(arraySize);
for(int i=0;i<arraySize;i++) {
    myArray[i]=i;
}
for(int i=0;i<arraySize;i++) {
    int randNum = (int)(Math.random() * (arraySize-1));
    int tmp=myArray[randNum];
    myArray[randNum]=myArray[i];
    myArray[i]=tmp;
}

答案 1 :(得分:2)

每次检查行时都会重新生成随机数,而不是将相同的数字与内部循环中的所有数组值进行比较。

你应该在这里做的是检查相同随机数的整个数组,如果你发现巧合,将k设置为0并重新生成随机数再试一次。

答案 2 :(得分:2)

您可以尝试以下代码:

public static void main(String[] args) {
    Set<Integer> set = new HashSet<>();
    while (set.size() < 10) set.add((int)(Math.random() * 31) + 1);
    Integer[] randArray = set.toArray(new Integer[0]);
    for (int i = 0; i < randArray.length; i++) {
        System.out.print(randArray[i] + " ");
    }
    System.out.println();
}

示例输出:

2 3 4 21 6 7 10 29 12 14

答案 3 :(得分:2)

我会使用 Fisher-Yates shuffle来执行此操作。这是我所知道的最快的方式,代价是内存消耗过多。但它不会受到任何重试开销的影响。

/*pseudocode; populate `arr` to taste. I'd be tempted to write it long-hand*/
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ..., 31}; 
/*Implement Fisher-Yates shuffle in its own scope block*/
{
    Random random = new Random();
    for (int i = arr.length - 1; i > 0; i--){
        int r = random.nextInt(i + 1);
        /*exhange r and i*/
        int t = arr[r];
        arr[r] = arr[i];
        arr[i] = r;
    }
}
/*ToDo - either rescale `arr` or just use the first 10 elements*/

答案 4 :(得分:2)

另一种解决方案。 标记生成的数字。

public static void main(String[] args) {
    int[] randArray = new int[10];
    int randNum = 0;
    boolean[] isPresented = new boolean[32];

    for (int i = 0; i < randArray.length; ) {
        randNum = (int)(Math.random() * 31 + 1);
        if(!isPresented[randNum]){
            randArray[i] = randNum ;
            isPresented[randNum] = true;
            i++;
        }
    }
    System.out.println(Arrays.toString(randArray));
}

答案 5 :(得分:1)

在第二个for循环中,您将为循环的每次迭代生成一个随机数。如下所示更改循环。

else {
            // generate a random number before the loop begins
            randNum = (int)(Math.random() * 31 + 1); 
            for (int k=0; k < randArray.length;) {

                if(randArray[k] == randNum) {
                    k=0;
                // generate a random number only if the number exists in the array
                    randNum = (int)(Math.random() * 31 + 1); 
                } else { 
                   k++;   
                }
            }
            randArray[j] = randNum;
            System.out.println(j);
        }

答案 6 :(得分:0)

据我所知,生成(非常大)一组独特随机数的最简单,最有效的方法是(它与Bathsheba建议的方法有些相似):

1)生成一个唯一序列号的ArrayList,以涵盖所有需要的范围 2)使用随机索引访问ArrayList并移动(从数组中获取和删除)索引处的条目。

这样,在ArrayList.size()迭代之后,你将得到一个唯一随机数的结果数组。