#题目:
水塘抽样是一组解决数据流取样的方法, 有很多的变种. 它适用的问题有如下特点:
1.对象为无法在内存中放下的数据, 如不间断数据流, 或者巨大的文件, 数组等. 2.样本集的大小为k, 并且要求每个样本的取样概率相等. 3.取样概率可以通过添加权重(weight)来改变取样概率. 一般(无weight)水塘抽样的每个样本的取样概率为: k/(n+1)
水塘抽样的算法实现非常简单, 而且证明简练. 算法如下:
1.预设数组A, 大小为k. 先取样k个元素. 放入A中. 2.从k+1元素开始, 每次取得随机数r, 范围为(0,k+1). 3.如果r <= k, A[r] = S[k+1], S是当前数据流.

public int[] sampling(InputStreamReader in, int k) throws IOException {
        int[] res = new int[k];
        int cur = 0;
        Random random = new Random();
        while (in.ready()) {
            int data = in.read();
            if (cur<k){
                res[cur] = data;
            }
            else {
                int r = random.nextInt(k+1);
                if (r < k)
                    res[r] = data;
            }
            cur++;
        }
        return res;
    }


最后再说一句:考虑一下这个问题,假设我们不知道集合S的大小,如何随机的取出一个元素 这么思考,这就是水塘问题:k=1的特例情况