随机取样问题

随机取样问题


输入包括两个整数m和n其中m>n,输出是0-m-1范围内的n个随机整数的有序列表,不允许重复。希望得到没有重复的有序选择,其中每个选择出现的概率相等

#include<iostream>
using namespace std;
int main()
{
    int n = 10;
    int m = 100;
    int selected = n;
    int remaining = m;
    srand(time(0));
    for(int i=0;i<m;i++)
    {
        if(rand()%(m-i) < n)
        {
            cout<<i<<" "<<m<<" "<<endl;
            n--;
        }
    }
    return 0;
}

 

 

当目标改为随机抽取n个有序整数

该算法时间和m成正比,当m很大而n很小时不合适

将算法啊改成在初始为空的集合里面插入随机整数,直到个数足够

#include<iostream>
#include<set>
using namespace std;
int main()
{
    int n = 10;
    int m = 100;
    int selected = n;
    int remaining = m;
    srand(time(0));
    set<int> s;
    while(s.size()<n)
    {
        s.insert(rand()%m);
    }
    set<int>::iterator ite;
    for(ite=s.begin();ite!=s.end();ite++)
    {
        cout<<*ite<<endl;
    }
    return 0;
}

 

利用set的特性,每个元素在set中只出现一次,因此在插入时无需判断是否已经插入过。
并且自动排序,输出时已经是有序的

 

但是插入操作每次都需要对红黑树进行调整,时间主要消耗在建立集合中

 


另一种方法:
将包含n个数的数组顺序打乱,然后把前m个元素排序输出
实际上只需要打乱前m个元素即可

void genshuf(int m, int n)
{
    int i, j;
    int *x = new int[m];
    for(i=0;i<m;i++)
        x[i]=i;
    for(i=0;i<n;i++)
    {
        j = randint(i, n-1);
        swap(x[i], x[j]);
    sort(x, x+n);
}


参考:编程珠玑

转载于:https://www.cnblogs.com/w0w0/archive/2012/08/16/2642490.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值