1

题目要求

从个元素中随机抽取个元素,但的个数无法事先确定。
在实际应用中,往往会遇到很大数据流的情况。因此,我们无法先保存整个数据流然后再从中选取,而是期望有一种将数据流遍历一遍就得到所选取的元素,并且保证得到的元素是随机的算法。

蓄水池抽样算法

先选取个元素中的前个元素,保存在集合中;
从第个元素开始,每次先以概率选择是否让第个元素留下。若第个元素存活,则从中随机选择一个元素并用该元素替换它;否则直接淘汰该元素;
重复1和2,直到结束。最后集合中剩下的就是保证随机抽取的个元素。

Java实现

public static BitSet randomBitSet(int size, int cardinality, Random rnd) {
        BitSet result = new BitSet(size);
        int[] chosen = new int[cardinality];
        int i;
        for (i = 0; i < cardinality; ++i) {
            chosen[i] = i;
            result.set(i);
        }
        for (; i < size; ++i) {
            int j = rnd.nextInt(i + 1);
            if (j < cardinality) {
                result.clear(chosen[j]);
                result.set(i);
                chosen[j] = i;
            }
        }
        return result;
    }

调用实例

boolean result = randomBitSet(100, outOf100, new Random()).get(i);

docs


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...