【问题标题】:Java how to add a Random Generator that excludes a certain number?Java如何添加排除某个数字的随机生成器?
【发布时间】:2013-11-11 15:37:18
【问题描述】:

假设我想从 ArrayList 中生成随机数:(1,2,3,4,5,6,7,8,9,10)

随机生成器产生 5。

列表已更新 - AL:(1,2,3,4,6,7,8,9,10)

下一个随机数不能是 5。


我正在编写一个从数组列表生成随机数的程序,一旦生成随机数,列表就会删除该数字,并且下一个随机生成的数字不能是该数字。

ArrayList<Integer> numsLeft = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));

  Random randomGenerator = new Random();

 int number = 0; 
 String cont;

 do
 {
 number = randomGenerator.nextInt(numsLeft.size()); 
 numsLeft.remove(number);

  System.out.println (number + " continue (y/n)");
  cont = (stdin.readLine());
 } 
 while (cont.equalsIgnoreCase("y"));      

但我在这里唯一能做的就是缩小尺寸......

http://docs.oracle.com/javase/7/docs/api/java/util/Random.html

【问题讨论】:

标签: java random arraylist


【解决方案1】:

更简单的方法是简单地打乱您的列表,然后使用打乱顺序中的数字:

List<Integer> nums = new ArrayList<Integer>();
for (int i = 1; i < 11; i++)
    nums.add(i);
Collections.shuffle(nums);

现在它们的顺序是随机的,只需一个一个地使用它们:

for (Integer i : nums) {
    // use i
}

【讨论】:

    【解决方案2】:

    您可以创建一个可用数字的数组。然后,随机数生成器为您提供所需数字在该数组中的位置。 可能链表或其他东西会更有效,但概念是一样的。 因此,以您的示例为例,您将第一次拉 5。第二次,你的列表中有这个: 1、2、3、4、6、7、8、9 如果您的随机数再次为 5,则第五个位置为 6。弹出六个,将 7、8、9 移到 1,然后将随机数生成器递减为 1-8 而不是 1-9。继续。

    当然,看看你的代码,看起来这就是你正在尝试做的事情。

    您的代码似乎有什么问题?你得到了什么结果?

    【讨论】:

      【解决方案3】:
      number = randomGenerator.nextInt(numsLeft.size()); 
      numsLeft.remove(number);
      

      您现在正在打印您正在生成的随机索引,而不是从列表中删除的数字。那是你想要的吗?我认为你的意思是:

      int index = randomGenerator.nextInt(numsLeft.size());
      number = numsLeft.remove(index);
      

      您也可以通过随机打乱列表然后浏览它来做到这一点:

      List<Integer> numsLeft = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));
      
      // Shuffle the list randomly
      Collections.shuffle(numsLeft);
      
      do {
          // Remove the first number each time
          int number = numsLeft.remove(0);
      
          System.out.println (number + " continue (y/n)");
          cont = (stdin.readLine());
      } while (cont.equalsIgnoreCase("y"));
      

      【讨论】:

        【解决方案4】:

        为什么不创建一个哈希映射来解决这个问题。所以你的哈希图可以包含类似

        Map[(1,1), (2,2), (3,3), ...] or Map[(1,true), (2,true), (3,true), ...]
        

        因此,如果您生成一个数字,那么您可以执行以下操作:

        String value = map.get(key); or boolean present = map.get(key); 
        
        if(value != null) or if(value == present)
        

        map.remove(key), 或者您甚至可以更新数据,而不是删除密钥,您可以更新它并添加单词删除或布尔值,如先前建议的那样。但是通过这种方式,您可以跟踪地图中每个键值的所有条目和删除,这将是您的数字列表。

        【讨论】:

          【解决方案5】:

          remove 在列表很长的情况下可能是相当昂贵的操作。随机播放也是如此 - 特别是如果您只需要几个数字。这是另一种算法(它很有名,但我现在找不到源)。

          1. 将您的 N(有序)数字放入列表中
          2. 在 0 到 N-1 之间选择一个随机数 m
          3. 选择位置 m 处的元素。这是您唯一的随机数
          4. 将元素 m 与数组中的最后一个元素交换
          5. 将 N 减 1
          6. 转到第 2 步

          您“搁置”了您在第 4 步中使用的数字 - 但是

          1. shuffle 不同,您的初始化速度很快
          2. remove 不同,您的 remove 操作只需要移动一个元素(而不是平均 N/2)
          3. 与“如果您以前看到过就选择一个并拒绝”不同,您选择“新”数字的效率不会随着选择的元素数量的增加而降低。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-22
            • 1970-01-01
            • 2020-09-04
            • 2014-03-21
            • 2013-10-17
            相关资源
            最近更新 更多