我谈到了一个API,它给了我java.util.Iterator一个集合.这意味着我可以迭代它,但我不能直接/随机访问元素.
现在我的问题:我想从这个集合中获得一个随机元素.我怎么做?我想我可以构建一个允许直接访问的新集合,但这不是一点消耗内存吗?我也可以迭代整个集合,并为每个元素"掷骰子",看看我是否应该采用该元素并退出迭代或继续.但后来我需要集合的大小,我无法从迭代器中获得.
提前致谢.
Bil*_*ard 10
有一种方法可以在一次通过集合时执行它,该集合不使用大量额外内存(只是集合中一个元素的大小加上一个浮点数).在伪代码中:
显然,这有一个缺点,就是每次调用它时都要遍历整个集合,但是你没有很多选择,而是面对你所面临的限制.
更新:此类问题的名称终于回到了我的面前.这称为水库采样.
迭代时,您知道已经迭代了多少个对象,因此您知道当前元素是随机选择的对象的概率.所以你只需要保持一个计数和当前随机选择的项目.
public static <T> T selectRandom(final Iterator<T> iter, final Random random) {
if (!iter.hasNext()) {
throw new IllegalArgumentException();
}
if (random == null) {
throw new NullPointerException();
}
T selected = iter.next();
int count = 1;
while (iter.hasNext()) {
final T current = iter.next();
++count;
if (random.nextInt(count) == 0) {
selected = current;
}
}
return selected;
}
Run Code Online (Sandbox Code Playgroud)
(Stack Overflow免责声明:未编译,当然未经过测试.)
另请参阅Collections.shuffleJava Puzzlers中的部分.
| 归档时间: |
|
| 查看次数: |
5570 次 |
| 最近记录: |