34

我想在 Java 中创建一组没有重复的随机数。

例如,我有一个数组来存储从 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);
        }
    }
}

但是上面的代码会创建重复项。如何确保随机数不重复?

4

12 回答 12

50
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));

}
于 2013-04-14T14:35:57.363 回答
9

可以在Programming Pearls p一书中找到一个简单的算法,它可以为您提供不重复的随机数。127.

注意:生成的数组按顺序包含数字!如果您希望它们以随机顺序排列,则必须使用Fisher-Yates shuffle或使用 List 和 call对数组进行洗牌Collections.shuffle()

这种算法的好处是您不需要创建一个包含所有可能数字的数组,并且运行时复杂度仍然是线性的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;
}
于 2015-04-20T14:04:33.090 回答
5

在 Java 8 中,如果你想在 中拥有一个list不重复的N随机整数range (a, b),其中b是独占的,你可以使用这样的东西:

Random random = new Random();
List<Integer> randomNumbers = random.ints(a, b).distinct().limit(N).boxed().collect(Collectors.toList());
于 2018-04-26T05:51:55.650 回答
4

Achintya Jha 的想法是正确的。您无需考虑如何删除重复项,而是首先删除创建重复项的能力。

如果您想坚持使用整数数组并希望随机化它们的顺序(手动,这很简单),请按照以下步骤操作。

  1. 创建大小为 n 的数组。
  2. 循环遍历索引 i 处的每个值并将其初始化为值 i(或 i+1,如果您希望数字 1 到 n 而不是 0 到 n-1)。
  3. 最后,再次循环遍历数组,将每个值交换为随机索引处的值。

您的代码可以修改为如下所示:

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;
        }
    }
}

如果我是你,我可能会将这些块中的每一个分解为单独的、更小的方法,而不是使用一个大的 main 方法。

希望这可以帮助。

于 2013-04-14T17:30:30.947 回答
3

如果您需要生成带间隔的数字,它可以是这样的:

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]

笔记:

如果你需要零不离开你可以放一个“如果”

于 2016-12-12T01:55:40.223 回答
0

这个怎么样?

LinkedHashSet<Integer> test = new LinkedHashSet<Integer>();
Random random = new Random();
do{
    test.add(random.nextInt(1000) + 1);
}while(test.size() != 1000);

然后,用户可以Set使用 for 循环遍历。

于 2016-04-28T09:48:46.273 回答
0

开始了!

public static int getRandomInt(int lower, int upper) {
    if(lower > upper) return 0;
    if(lower == upper) return lower;
    int difference = upper - lower;
    int start = getRandomInt();
    
    //nonneg int in the range 0..difference - 1
    start = Math.abs(start) % (difference+1);
    
    start += lower;
    return start;
}

public static void main(String[] args){
    
    List<Integer> a= new ArrayList();
    
    int i;
    int c=0;
    for(;;) {
        c++;
        i= getRandomInt(100, 500000);
        if(!(a.contains(i))) {
            a.add(i);
            if (c == 10000) break;
            System.out.println(i);
        }
        
        
    }
    
    for(int rand : a) {
        System.out.println(rand);
    }
    
    
    
}

获取随机数 返回一个随机整数 x,满足 lower <= x <= upper。如果 lower > upper,则返回 0。@param lower @param upper @return

在我创建列表的主要方法中,然后我检查列表中是否存在随机数,如果不存在,我会将随机数添加到列表中

这是非常缓慢但直截了当的。

于 2019-10-19T03:14:41.217 回答
0

如果您使用的是 JAVA 8 或以上版本,请按照以下方式使用流功能,

Stream.generate(() -> (new Random()).nextInt(10000)).distinct().limit(10000);
于 2020-11-10T05:06:59.590 回答
0
public class RandomNum {
    public static void main(String[] args) {
        Random rn = new Random();
        HashSet<Integer> hSet = new HashSet<>();
        while(hSet.size() != 1000) {
            hSet.add(rn.nextInt(1000));
        }
        System.out.println(hSet);
    }
}
于 2020-12-04T13:04:59.183 回答
0

一个简单的流解决方案:

   new Random().ints(0, 10000)
        .distinct()
        .limit(10000)
        .forEach(System.out::println);
于 2021-03-17T21:28:13.243 回答
-1
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();
            }
        }

    }
}
}
于 2014-07-11T07:07:48.427 回答
-1
HashSet<Integer>hashSet=new HashSet<>();
Random random = new Random();
//now add random number to this set
while(true)
{
    hashSet.add(random.nextInt(1000));
    if(hashSet.size()==1000)
        break;
}
于 2018-09-20T09:39:57.023 回答