1

假设我想生成取自 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

4

5 回答 5

6

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

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
}
于 2013-11-11T15:45:58.680 回答
0

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

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

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

于 2013-11-11T15:41:38.907 回答
0
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"));
于 2013-11-11T15:41:43.877 回答
0

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

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

于 2013-11-11T16:06:35.903 回答
0

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. 与“如果您以前看到过就选择并拒绝”不同,您选择“新”数字的效率不会随着选择的元素数量的增加而降低。
于 2013-11-16T00:05:48.830 回答