【编程珠玑】学习笔记5——抽样问题

本文介绍了如何在C++中生成至少30个随机位的整数,以及实现randint(l,u)函数来获取指定范围内的随机数。此外,还探讨了三种生成m个0到n-1之间不重复且有序随机数的方法:genknuth、gensets和genshuf,并通过实测对比了它们的时间性能。" 128851953,17257020,使用vue-qrcodejs2生成二维码指南,"['vue.js', 'javascript', '前端']
摘要由CSDN通过智能技术生成

前言:C库中的rand()函数大概随机返回15个随机位的整数,可以在该方法的基础上生成至少30个随机位的整数,并实现返回一个(l-u)之间的随机数的函数randint(l,u)。

bigrand()函数(生成至少30个随机位的整数)

int  bigrand()

{

       return ( rand()*RAND_MAX + rand() );

}

备注:常量 RAND_MAX 是可以由rand 函数返回的最大值。 RAND_MAX 的定义在stdlib.h中,值为 0x7fff。


int  randint(int m, int n)

{

       return  ( m + rand()%(n-m+1) );

}

在生成随机数的过程中,为了保证统一线程中每次生成的随机数不一样,需要引入srand函数生成随机数种子,srand函数原型为:

void  srand( unsigned int  seed );

seed表示伪随机数种子,可以为getpid()或者time(0)的返回值。


下面是生成 m 个0 - n-1之间不重复且有序的随机数的方法

void genknuth(int m,int n)
{
for(int i=0;i<n;i++)
{
//select m of remaining (n-i)
if((bigrand()%(n-i)) < m)
{
cout << i <<" ";
m--;
}
}
}


void gensets(int m,int n)
{
set<int> S;
while(S.size() < m)
{
S.insert(bigrand() % n);
}
set<int>::iterator it;
for(it = S.begin();it != S.end(); it++)
{
cout <<*it<<" ";
}
}


void genshuf(int m,int n,ofstream &out)
{
int i,j;
int *x = new int[n];   //生成0-n-1的n个数
for(i=0;i<n;i++)
{
x[i] = i;
}
for(i=0;i<m;i++)
{
j = randint(i,n-1); //打乱顺序后选取前m个值
int tmp;
tmp = x[i];
x[i] = x[j];
x[j] = tmp;
}
sort(x,x+m);             //再对前m个数排序
for(i = 0;i<m;i++)
{
out << x[i]<<" ";
}
}

我在自己的机子上测了一下用上述3种方法生成1-2000000之间不重复的1000000个随机数,用时基本相同,在9s左右。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值