(算法)等概率选出m个整数

题目:

从大小为n的整数数组A中随机选出m个整数,要求每个元素被选中的概率相同。

思路:

n选m,等概率情况下,每个数被选中的概率为m/n。

方法:

初始化:从A中选择前m个元素作为初始数组;

随机选择:从第m个元素开始,依次遍历数组下标i,并通过随机生成器生成数字k(生成0~n),如果k<m,则将A[i]替换A[k]。

证明:

归纳法:假设数组A大小为n,需要选m个元素,每个元素被选中的概率为m/n。

对于初始化的m个元素而言,其选中的概率自然为m/n;

而对于第n+1个元素,该元素被选中的概率m/(n+1)(根据随机生成器),

而对于此时前m个元素,根据第n+1个元素的选中与否情况:

第n+1个没选中的概率为1-m/(n+1),则全部留下的可能性为P1:m/n*(1-m/n+1),

第n+1个被选中的概率为m/(n+1)有一个被替换后留下的可能性为P2:m/n*m/(n+1)*(m-1)/m,

总的留下概率为:P1+P2=m/(n+1)

因此得证。

代码:

#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<vector>

using namespace std;

void pickM(const vector<int> &A,int m,vector<int> &pick){
    int n=A.size();
    
    for(int i=0;i<m;i++){
        pick.push_back(A[i]);
    }

    srand((unsigned)time(0));
    for(int i=m;i<n;i++){
        int k=rand()%n;
        if(k<m)
            pick[k]=A[i];
    }
}

int main(){
    int m,n;
    while(cin>>n>>m){
        vector<int> A(n);
        for(int i=0;i<n;i++)
            cin>>A[i];

        vector<int> pick;
        pickM(A,m,pick);        

        for(int i=0;i<m;i++)
            cout<<pick[i]<<" ";
        cout<<endl;
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值