使用唯一数字随机化长数组

时间:2018-03-14 10:19:38

标签: java arrays for-loop random

我试图以随机顺序组成由数字0 - 9组成的长数组,这意味着不会有相同数字的重复数据。我是一名新手编码员,这就是我试图提出来的。

    public static void shuffle() 
{
    long[] rn = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    Random rand = new Random();

    for (int i = 0; i < 10; i++) {
        int n;
        n = rand.nextInt(10) + 0;

        for (int j = 0; j < 10; j++) 
        {
            if (n != rn[j]) 
            {
               j++; 
            }
            else if (n == rn[j]) 
            {

                n = rand.nextInt(10) + 0;
                if (j > 0) 
                {
                    j--;
                }
            }
        }
        rn[i] = n;
    }

    for (int l = 0; l < 10; l++) 
    {
        System.out.print(rn[l]);
    }
    System.out.println();

}

根据我的理解,这不应该让任何重复的数字通过,但确实如此。我做错什么了吗?

PS:我不允许使用集合或数组列表。我使用的是Ready To Program IDE,它显然不支持这些。

2 个答案:

答案 0 :(得分:0)

所以第二个。它有很多缺陷。

只有当你真正知道自己的所作所为时,才应该在代码内部更改for变量。

if (n != rn[j]){
    j++; 
}

那是错误的=&gt;您将跳过一些元素,因为您已经在for循环中增加了变量。所以在每次迭代中你都会增加+2。

但是因为你想在一次测试失败时再次从头开始检查所有其他元素,你必须放入else部分j = -1。 为什么-1?因为在for循环的最后一步,for循环会将它增加1,所以你将再次从0开始。

j = -1;

当您更改上面的那个以便不增加它时,您将遇到一个永无止境的循环。 原因是,你用零填充它。你会用10或其他数字(不是0-9)填写它不会发生。 因此,一种方法是用其他数字填充数组,或者只检查用随机数填充的前i个数字:

for (int j = 0; j < i; j++) 

最后这应该有效:

for (int i = 0; i < 10; i++) {
    int n;
    n = rand.nextInt(10);

    for (int j = 0; j < i; j++) 
    {
        if (n == rn[j]) 
        {

            n = rand.nextInt(10);
            j = -1;
        }
    }
    rn[i] = n;
}

答案 1 :(得分:-1)

你确实在做一些特殊的事情。

  • 更改循环变量 - 大多数情况下,当需要一些严重的魔法时,应该只修改循环变量(ij)否则,循环变量应该保持不变。
  • Voodooish + 0 - 在值中添加0毫无意义。

关于你的shuffle方法,我提出了另一种方法。循环中有一个循环,因此当数组较大时,执行时间将呈指数级增长。

相反,也可以从源数组中选择一个随机索引,然后使用该值填充新数组的下一个位置。当然,为了避免源数组中的值被拾取两次,我们将该值与源数组的最后位置上的值交换并减小其大小。

index | 0 | 1 | 2 | 3 | 4  |
value | 2 | 3 | 5 | 7 | 11 |
arraySize: 5

Step 1. Pick random index, where index is less than arraySize
(in this example index 1 has been picked)

index | 0 | 1 | 2 | 3 |  4 |
value | 2 | 3 | 5 | 7 | 11 |
arraySize: 5
pickedIndex: 1

Step 2. Swap value at pickedIndex with value at index arraySize − 1

index | 0 |  1 | 2 | 3 | 4 |
value | 2 | 11 | 5 | 7 | 3 |
arraySize: 5

Step 3. Decrease array size, so the value previously on the picked
position won't be picked again

index | 0 |  1 | 2 | 3 |
value | 2 | 11 | 5 | 7 |
array size: 4

代码如下所示:

private static int[] shuffle(int[] array) {
    int[] availableNumbers = new int[array.length];
    int availableNumbersLength = availableNumbers.length;
    System.arraycopy(array, 0, availableNumbers, 0, array.length);
    int[] shuffledArray = new int[availableNumbers.length];

    Random r = new Random();
    for (int i = 0; i < availableNumbers.length; i++) {
        int index = r.nextInt(availableNumbersLength);
        shuffledArray[i] = availableNumbers[index];
        availableNumbers[index] = availableNumbers[availableNumbersLength - 1];
        availableNumbersLength--;
    }
    return shuffledArray;
}

请注意,我复制了输入数组,以便保持源数组不变,并返回包含随机顺序元素的新数组。当然,你也可以随机播放原始阵列。