入门级的随机数生成工具

        今天为了想做个排序算法的小实验,自己写了一个生成不重复的随机数组的工具。

        关于随机数的生成,网络上最广泛的例子就是利用rand()、srand()和time()三个Linux自带库函数组成的随机数生成模块。其代码如下:

static unsigned int CreateRamdomNum(void)
{
	srand(time(NULL));
	return rand();
}

        我上网查找了许多资料,发现生成数组的办法有很多种。

         一种是不断遍历,发现重复就丢弃生成出来的随机数重新生成;还有一种是把生成过的随机数从随机数生成器中剔除;还有更高端的是用离散数学的方法(太高端了我也看不懂,就不说了)...本人才疏学浅,用了最笨的办法,发现重复的就丢掉重来,用于生成数组的代码如下:

unsigned int *CreateRamdomArray(unsigned int num)
{
	unsigned int *p_head;
	int i,j;

	p_head = (unsigned int*)malloc(sizeof(unsigned int)*num);
	if(NULL == p_head){
		perror("Application of memory failed!\n");
		return NULL;
	}

	memset(p_head,0,sizeof(unsigned int)*num);

	for(i=0; i<num; i++){
		*(p_head + i) = CreateRamdomNum();
		
		for(j=0; j<i; j++){
			if(*(p_head + i) == *(p_head + j)){
				*(p_head + i) = CreateRamdomNum();
				j = -1;
			}
		}
	}
	return p_head;
}
         运行之后发现用这种方法生成不重复的随机数组不是一般的低,生成一个20个不重复随机数的数组需要20多秒的时间。刚开始我以为是自己的程序设计有问题,经过一番改良优化之后发现还是“然并卵”,整个程序的运行时间并没缩短多少。

         经过几次运行后发现一个规律,用这种方法生成一个10个随机数的数组的时间大约为10秒,生成一个30个随机数数组的时间大约就30秒,生成5个也要等上5秒...本人的老爷机虽说已经上了年纪,但也不至于效率这么低吧?


        于是我仔细阅读了下time()的说明,发现其计时的最小精度为秒。而rand函数在同一个srand设定下只会生成相同的伪随机数。也就是说,在1秒之内,不管CPU性能多么高,跑得多欢快,time返回值不变,导致srand设置的种子也是同一个,自然rand也只会生成重复的数!根据本人的数组生成办法,就只能把生成出来的数值丢掉,再来一遍,直到time返回的值有变化为止!难怪生成20个就刚好花了20秒。

         于是我又上网查找了一番资料,把生成随机数的模块改成这样子:

static unsigned int CreateRamdomNum(unsigned int input)
{
	static struct timeval str_TimeVal;

	if(input){
		gettimeofday(&str_TimeVal,NULL);
		srand(str_TimeVal.tv_usec);
	}
	else{
		srand(time(NULL));
	}
	return (unsigned int)rand();
}

        这里新增了一个Linux的库函数gettimeofday该函数的原型如下:

#include <sys/time.h>
int gettimeofday(struct timeval *tv,struct timezone *tz);

/* 而结构体timeval的定义为 */
struct timeval{
    long int tv_sec; // 秒数
    long int tv_usec; // 微秒数};

        重新编译再跑了一遍,运行时间0.1s!即使是生成30个不重复的随机数数组时间也在1秒之内。QTN的time,以后再也不想用它了...

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值