简体   繁体   English

如何生成特定范围内的唯一随机数

[英]how to generate unique random numbers with a specific range

i want to generate 255 unique random numbers within this range (0-255). 我想在此范围内(0-255)产生255个唯一的随机数。 so that the array will not contain duplicate records 这样数组就不会包含重复的记录

short [] array =new short[255];
Random rand = new Random();
boolean   flag=false;
for (int i=0;i<array.length;i++){
    int random_integer = rand.nextInt(255-0) + 0;
    for (int j=0;j<i;j++){
        if ((short)random_integer==array[j]){
            flag=true;
        }
    }
    if (flag==false){
        array[i]=(short)random_integer;  
    }
}
for (int i=0;i<array.length;i++){
    System.out.println(array[i]);
} 

but i get only first 20 0r 30 items with values and the rest of the array items equals zero. 但是我只得到前20个0r 30个具有值的项,其余的数组项等于零。

Solution 1: 解决方案1:

I read Jon Skeet's comment, of course, this is the easiest solution: 我阅读了Jon Skeet的评论,当然,这是最简单的解决方案:

List<Integer> list = new ArrayList<>();
for (int i = 0; i < 255; i++) {
     list.add(i);
}
//and here is the point. Java already have this implemented for you
Collections.shuffle(list);

Or in Java 8 declarative style: 或采用Java 8声明式:

List<Integer> list= IntStream.range(0, 255)
    .boxed()
    .collect(Collectors.toList());
Collections.shuffle(list);

or 要么

List<Integer> list = new ArrayList<>();
IntStream.range(0, 255).forEach(list::add);
Collections.shuffle(list);

Solution 2 (picking up on your solution): 解决方案2(了解您的解决方案):

You need to generate number for each cell, and check if this number already exists: 您需要为每个单元格生成一个数字,并检查该数字是否已经存在:

 short [] array =new short[255];
 Random rand = new Random();

 for (int i=0; i<array.length; i++) {
     int random_integer = -1;

     //generate integer while it exists in the array
     while(exists(random_integer, array)) {
         random_integer = rand.nextInt(255);
     }

     array[i] = random_integer;
}

And now, let's check whether it exists: 现在,让我们检查它是否存在:

public boolean exists(int number, int[] array) {
    if (number == -1)
        return true; 

    for (int i=0; i<array.length; i++) {
        if (number == array[i])
            return true;
    }
    return false;
}

Of course, you can use a hashmap for example, to speed up the exists() method, ie to lower the complexity from O(n) to O(1); 当然,例如,您可以使用哈希图来加速exist exists()方法,即将复杂度从O(n)降低到O(1);

如果可以使用Java 8:

List<Integer> randIntegers = new Random().ints(1, 256).distinct().limit(255).boxed().collect(Collectors.toList());

You check if the random number existed, but you do not reset the flag to false in your loop, so as soon as the first duplicate number comes, nothing happens anymore, because flag is always true. 您检查是否存在随机数,但不要在循环中将标志重置为false,因此,一旦第一个重复数字出现,就不再发生任何事情,因为标志始终为true。

You also should build in somthing like: 您还应该内置以下内容:

if ((short)random_integer==array[j]){
  flag=true;
  i--;
}

to make sure to revisit an index of your array after you skipped it for a duplicate number. 以确保在跳过重复编号后重新访问数组的索引。

public static void main(String ar[]){
short [] array =new short[255];
Random rand = new Random();
int random_integer;
boolean   flag=false;
for (int i=0;i<array.length;i++){
     random_integer = rand.nextInt();
     for (int j=0;j<i;j++){
         if ((short)random_integer==array[j]){
                 flag=true;
                 i--;
            }
      }
      if (flag==false)
        array[i]=(short)random_integer;  
}
for (int i=0;i<array.length;i++)
    System.out.print(" "+array[i]);
System.out.println();
}

You need to reset flag value in every iteration or change your logic: 您需要在每次迭代中重置flag值或更改逻辑:

       for (int j=0;j<i;j++){
                flag=false;//<--
                if ((short)random_integer==array[j]){
                    flag=true;
                }
            }

Did you considered creating an HashSet and putting values you've used in it? 您是否考虑过创建HashSet并放入您使用过的值? Then your code should look like this: 然后您的代码应如下所示:

HashSet hs = new HashSet();
short [] array =new short[255];
Random rand = new Random();

for (int i=0;i<array.length;i++){
int random_integer = rand.nextInt(255-0);
if (!hs.contains(random_integer ))
{
array[i]=(short)random_integer;  
hs.put(random_integer);
}
else{ //generate new integer}
}

It is very hard to read the code without the proper indentation. 没有适当的缩进,很难阅读代码。

Anyhow - you don't do anything if flag == true . 无论如何-如果flag == true您什么也不做。 So obviously you don't fill many places in the array. 因此,显然您不会在数组中填充很多位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM