Java生成非重复的随机数
我想在Java中创build一组没有重复的随机数字。
例如我有一个数组来存储从0到9999的10,000个随机整数。
这是我到目前为止:
import java.util.Random; public class Sort{ public static void main(String[] args){ int[] nums = new int[10000]; Random randomGenerator = new Random(); for (int i = 0; i < nums.length; ++i){ nums[i] = randomGenerator.nextInt(10000); } } }
但是上面的代码会创build重复项。 我怎样才能确保随机数字不重复?
Integer[] arr = {...}; Collections.shuffle(Arrays.asList(arr));
例如:
public static void main(String[] args) { Integer[] arr = new Integer[1000]; for (int i = 0; i < arr.length; i++) { arr[i] = i; } Collections.shuffle(Arrays.asList(arr)); System.out.println(Arrays.toString(arr)); }
一个简单的algorithm,给你随机数字没有重复,可以发现在书中编程珍珠页。 127。
注意 :结果数组按顺序包含数字! 如果你想随机select它们,你必须用Fisher-Yates shuffle或者使用List来调用Collections.shuffle()
。
这个algorithm的好处是你不需要用所有可能的数字创build一个数组,运行时复杂度仍然是线性的O(n)
。
public static int[] sampleRandomNumbersWithoutRepetition(int start, int end, int count) { Random rng = new Random(); int[] result = new int[count]; int cur = 0; int remaining = end - start; for (int i = start; i < end && count > 0; i++) { double probability = rng.nextDouble(); if (probability < ((double) count) / (double) remaining) { count--; result[cur++] = i; } remaining--; } return result; }
Achintya Jha在这里有正确的想法。 不要考虑如何删除重复项,而是首先删除创build重复项的function。
如果您想要使用一系列整数并想要随机化它们的顺序(手动,这非常简单),请按照下列步骤操作。
- 创build大小为n的数组。
- 循环并将索引i中的每个值初始化为值i(或如果希望将数字1到n而不是0到n-1,则为i + 1)。
- 最后,循环遍历数组,再次交换每个值的随机索引值。
你的代码可以修改成如下所示:
import java.util.Random; public class Sort { // use a constant rather than having the "magic number" 10000 scattered about public static final int N = 10000; public static void main(String[] args) { //array to store N random integers (0 - N-1) int[] nums = new int[N]; // initialize each value at index i to the value i for (int i = 0; i < nums.length; ++i) { nums[i] = i; } Random randomGenerator = new Random(); int randomIndex; // the randomly selected index each time through the loop int randomValue; // the value at nums[randomIndex] each time through the loop // randomize order of values for(int i = 0; i < nums.length; ++i) { // select a random index randomIndex = randomGenerator.nextInt(nums.length); // swap values randomValue = nums[randomIndex]; nums[randomIndex] = nums[i]; nums[i] = randomValue; } } }
如果我是你,我可能会把每一个块分成更小的方法,而不是采用一个大的主要方法。
希望这可以帮助。
如果你需要间隔产生数字,它可以是这样的:
Integer[] arr = new Integer[((int) (Math.random() * (16 - 30) + 30))]; for (int i = 0; i < arr.length; i++) { arr[i] = i; } Collections.shuffle(Arrays.asList(arr)); System.out.println(Arrays.toString(arr));`
结果:
[1, 10, 2, 4, 9, 8, 7, 13, 18, 17, 5, 21, 12, 16, 23, 20, 6, 0, 22, 14, 24, 15, 3, 11, 19]
注意:
如果你需要的零不离开你可以把一个“如果”
这个怎么样?
LinkedHashSet<Integer> test = new LinkedHashSet<Integer>(); Random random = new Random(); do{ test.add(random.nextInt(1000) + 1); }while(test.size() != 1000);
然后用户可以使用for循环遍历Set
。
public class Randoms { static int z, a = 1111, b = 9999, r; public static void main(String ... args[]) { rand(); } public static void rand() { Random ran = new Random(); for (int i = 1; i == 1; i++) { z = ran.nextInt(b - a + 1) + a; System.out.println(z); randcheck(); } } private static void randcheck() { for (int i = 3; i >= 0; i--) { if (z != 0) { r = z % 10; arr[i] = r; z = z / 10; } } for (int i = 0; i <= 3; i++) { for (int j = i + 1; j <= 3; j++) { if (arr[i] == arr[j]) { rand(); } } } } }