生成不重复的随机数的方法

《编程珠玑》有一题,需要生成0~10^7的不重复随机数。
最简单最直接的方法是,每次生成一个,然后和已经生成的进行比较,如果有了,那就重新生成。但一个显然的事实是,如果我要产生很多的数,越到后面所要花费的时间将越多。
如何又快又好的产生呢?

我们可以换个角度考虑问题,每次随机产生的可以不是具体的数,而是数在数组中的位置。算法的示意图如下:

 

#define MAXINT (10000000)
void myswap(int &a,int &b);
void getRandoms(int k);
 
void myswap(int &a,int &b)
{
    int tmp=a;
    a=b;
    b=tmp;
}
 
void getRandoms(int k)
{
    int* allint;
    int i=0;
    FILE *fp;
 
    if(k>MAXINT ||k<=0)
        return;
    srand(time(NULL));
    allint=(int *)malloc(sizeof(int)*MAXINT);
    for( i=0;i<MAXINT;i++)
    {
        allint[i]=i;
    }
    for(i=(MAXINT-1);i>=(MAXINT-k);i--)
    {
        myswap(allint[i],allint[rand()%(i+1)]);
    }
    if((fp=fopen("data.dat","w+b"))==NULL)
    {
        printf("not open");
        exit(0);
    }
    fwrite(allint+MAXINT-k,sizeof(int),k,fp);
    fclose(fp);
    free(allint);
}
 
int main(int argc, char* argv[])
{
    getRandoms(MAXINT);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值