0

我需要生成一个int[] randomNumbers没有重复的随机数数组。为此,我创建了一个包含所有可以进入的值的数组randomNumbers,然后使用随机数生成器从列表中选择一个,检查它是否已经在 中randomNumbers,如果不是,则将其放入randomNumbers

(我想要 1 和 max 之间的数字,而不是 0 和 max-1)

为了能够使用 Arrays.sort(int[]),需要对列表进行排序。因此,我使用第三个数组,其值与randomNumberscalled相同sortedNumbers,并在每次迭代时对其进行排序:

public int[] uniqueRandom(int max, int numRequired) {
    if (max < numRequired) {
        numRequired = max;
    }
    int[] randomNumbers = new int[numRequired];
    int[] sortedNumbers = new int[numRequired];
    int[] sequentialNumbers = new int[max];
    for (int i = 1; i < max; i++) {
        sequentialNumbers[i] = i;
            System.out.println(sequentialNumbers[i]);
    }

    int p = 0;
    while (p < numRequired) {
        int j = r.nextInt(max) + 1;
        System.out.println("J:" + j);
        if (Arrays.binarySearch(sortedNumbers, j) >= 0) {
            System.out.println("Number Found:" + Arrays.binarySearch(randomNumbers,  j));
        } else {
            randomNumbers[p] = j;
            sortedNumbers[p] = j;
            Arrays.sort(sortedNumbers);
            for (int i = 0; i < randomNumbers.length; i++) {
                System.out.println("rNum[" + i + "]:" + randomNumbers[i]);
            }
            System.out.println("\n");
            for (int i = 0; i < randomNumbers.length; i++) {
                System.out.println("sNum[" + i + "]:" + sortedNumbers[i]);
            }
            p++;
        }

    }

    return randomNumbers;
}

我的问题是我得到一个sortedNumbers覆盖值的输出。对于 uniqueRandom(5, 5),输出为:

J:2
rNum[0]:2
rNum[1]:0
rNum[2]:0
rNum[3]:0
rNum[4]:0

sNum[0]:0
sNum[1]:0
sNum[2]:0
sNum[3]:0
sNum[4]:2


J:2 // 2 already in the list, try again


J:2


J:4
rNum[0]:2
rNum[1]:4
rNum[2]:0
rNum[3]:0
rNum[4]:0

sNum[0]:0
sNum[1]:0
sNum[2]:0
sNum[3]:2
sNum[4]:4


J:5
rNum[0]:2
rNum[1]:4
rNum[2]:5
rNum[3]:0
rNum[4]:0

sNum[0]:0
sNum[1]:0
sNum[2]:2
sNum[3]:4
sNum[4]:5


J:2


J:3
rNum[0]:2
rNum[1]:4
rNum[2]:5
rNum[3]:3
rNum[4]:0

sNum[0]:0  // Should be:
sNum[1]:0  // 2
sNum[2]:2  // 3
sNum[3]:3  // 4
sNum[4]:5  // 5


J:4
rNum[0]:2
rNum[1]:4
rNum[2]:5
rNum[3]:3
rNum[4]:4

sNum[0]:0
sNum[1]:0
sNum[2]:2
sNum[3]:3
sNum[4]:4

所以你可以看到问题。我正在使用 java 1.7,但不知道为什么要这样做!

4

5 回答 5

2

您正在使用相同的索引将新数字放入两个数组中。您的 rNum 数组是从上到下填充的,但排序后的数组不是:每次排序时,新值在数组中向下移动,并且零总是在顶部。我认为您可以通过始终将新数字放在排序数组的第一个位置来解决它:

sortedNumbers[0] = j;
于 2012-10-25T12:53:56.787 回答
2

为了解决您的问题,我会使用一个集合,以确保我们获得独特的结果。

下面的 snipest 将生成具有所需数量的唯一整数的数组。

Set<Integer> uniqueNumbers = new HashSet<Integer>();
Random r = new Random();
while(uniqueNumbers.size() < numRequired) {
    uniqueNumbers.add(r.nextInt(maxRandom) + 1);
} 
return uniqueNumbers.toArray(new Integer[0]);
于 2012-10-25T12:55:55.397 回答
0

当你输入 J=5

sortedNUM[] 是

sNum[0]:0
sNum[1]:0
sNum[2]:2
sNum[3]:4
sNum[4]:5

接下来当你输入 J=3 (你的 p=3) 之后

sortedNumbers[p] = j;

你的 sNUM[3] 是 4 被 3 替换,因此在排序后它变成

sNum[0]:0  // Should be:
sNum[1]:0  // 2
sNum[2]:2  // 3
sNum[3]:3  // 4
sNum[4]:5  // 5

通知 4 不存在

我建议您将数组初始化为 -1 或 0 并在数组的开头添加变量,例如

sortedNumbers[0]=j;

在 Arrays.sort(); 之后 第一个位置将始终为空以添加更多数字

于 2012-10-25T12:59:19.543 回答
0

虽然它没有回答这个问题,但这里有一个替代方案,O(n)并且工作得很好,前提max是不是很大。

public static void main(String[] args) {
    System.out.println(Arrays.toString(uniqueRandom(20, 10)));
}

public static int[] uniqueRandom(int max, int numRequired) {
    int[] possible = new int[max];
    int[] ret = new int[numRequired];
    for (int i = 0; i < max; i++)
        possible[i] = i + 1;
    Random r = new Random();
    int numLeft = max;
    for (int i = 0; i < numRequired; i++) {
        int idx = r.nextInt(numLeft);
        ret[i] = possible[idx];
        if (idx < --numLeft)
            possible[idx] = possible[numLeft];
    }
    return ret;
}

印刷

[4, 10, 12, 19, 8, 3, 15, 1, 14, 7]

我想说的是,也许你可以让它更简单。

于 2012-10-25T13:11:23.647 回答
0

您的代码存在一些问题:

  • 因为您仅在数组中尚不存在新数字 j 时才增加 p ,因此,再加上您首先对 sortedArray 进行排序这一事实导致该值有时实际上被放置在现有值之上(由于种类)

  • 我不明白sequentialNumbers数组的用途是什么......

这是一个应该有效的示例:

private static Random r = new Random();

public static void main(String[] args) {
    System.out.println(Arrays.toString(uniqueRandom(10, 10)));
}

public static int[] uniqueRandom(int max, int numRequired) {
    if (max < numRequired) {
        numRequired = max;
    }
    int[] randomNumbers = new int[numRequired];
    int[] sortedNumbers = new int[numRequired];
    Arrays.sort(sortedNumbers);

    int p = 0;

    while (p < numRequired) {
        int j = r.nextInt(max) + 1;         
        if(Arrays.binarySearch(sortedNumbers, j)<0) {
            randomNumbers[p] = j;
            System.arraycopy(randomNumbers, 0, sortedNumbers, 0, randomNumbers.length);
            Arrays.sort(sortedNumbers);
            p++;
        }           
    }

    return randomNumbers;
}
于 2012-10-25T13:18:10.497 回答