【问题标题】:how to generate unique random numbers with a specific range如何生成具有特定范围的唯一随机数
【发布时间】:2015-10-28 04:06:00
【问题描述】:

我想在这个范围 (0-255) 内生成 255 个唯一随机数。这样数组就不会包含重复的记录

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

但我只得到前 20 0r 30 个具有值的项目,其余的数组项目为零。

【问题讨论】:

  • 有什么理由不只生成集合中的所有值然后对其进行随机播放?

标签: java arrays random numbers


【解决方案1】:

解决方案 1:

我看了 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);

或者在 Java 8 声明式风格中:

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

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

解决方案 2(选择您的解决方案):

您需要为每个单元格生成编号,并检查该编号是否已经存在:

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

现在,让我们检查一下它是否存在:

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

当然,您可以使用 hashmap 来加速exists() 方法,即将复杂度从 O(n) 降低到 O(1);

【讨论】:

  • 您不是在迭代列表 .size() 时对其进行修改吗?不应该是for (int i = 0; i &lt; range; i++)吗?
  • @Bar 啊,你是对的......是的,它应该在那里。
【解决方案2】:

如果你可以使用java 8:

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

【讨论】:

    【解决方案3】:

    您检查随机数是否存在,但您没有在循环中将标志重置为 false,因此一旦第一个重复数字出现,就不会再发生任何事情,因为标志始终为真。

    你还应该构建类似的东西:

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

    确保在跳过重复数字后重新访问数组的索引。

    【讨论】:

      【解决方案4】:
      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();
      }
      

      【讨论】:

        【解决方案5】:

        您需要在每次迭代中重置 flag 值或更改您的逻辑:

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

        【讨论】:

          【解决方案6】:

          您是否考虑过创建一个 HashSet 并将您使用过的值放入其中? 那么你的代码应该是这样的:

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

          【讨论】:

            【解决方案7】:

            如果没有适当的缩进,很难阅读代码。

            无论如何 - 如果flag == true,你什么都不做。所以很明显你不会在数组中填充很多地方。

            【讨论】:

              猜你喜欢
              • 2013-12-14
              • 2012-04-13
              • 2012-08-19
              • 2016-05-04
              • 1970-01-01
              • 1970-01-01
              • 2014-01-29
              相关资源
              最近更新 更多