用时间做种子生成随机数


   【转】 用时间做种子生成随机数              
分类: VC++ 2768人阅读 评论(0) 收藏 举报

我们知道rand()函数可以生成随机数,其实是在种子的基础上做某种变换并返回生成的随机数。在默认情况下,种子是1。写一个小程序测试一下。

 

  1. main()  
  2. {  
  3. int i,j;  
  4. for(i=0;i<10;i++)  
  5. {  
  6. j=1+(int)(10.0*rand()/(RAND_MAX+1.0));  
  7. cout<<j<<endl;  
  8. }  
  9. }    
  10.    执行:9 4 8 8 10 2 4 8 3 6   

每次执行结果都是 9 4 8 8 10 2 4 8 3 6。在没有修改种子的情况下,程序每次运行都会产生相同的一组随机数。

可以调用srand(unsigned seed)修改种子,这样先后两次运行的程序就会产生的随机数就会不同。一般会选用时间作为种子,例如:

srand((unsigned)time(NULL));

这样种子会随时间在变,产生的随机数重复的可能性就小。但是这里还存在一个问题:time返回的是距离1970.01.01零时的秒数 ,如果rand函数在1s内调用多次,那么产生的数据是相同的。可以用下面的代码进行测试。

  1. for (int i = 0;i<1000;++i)  
  2.     std::cout<<randSelectQuestion(1,1000)<<'/t';  

 

  1. int randSelectQuestion(int from,int to)  
  2. {//在from和to号之间选择一个数字  
  3.     srand((unsigned)time(NULL));  
  4.     int span = 0;  
  5.     if (to>from)  
  6.     {  
  7.         span = to - from;  
  8.         return from+rand()%span;  
  9.     }  
  10.     else  
  11.     {  
  12.         span = from - to;  
  13.         return to+rand()%span;  
  14.     }     
  15. }  

运行上面的程序,会发现随机数重复相当厉害。根据随机数生成的原理,我们可以让种子变化快一些来降低重复概率:将time()换成clock(),clock----

Calculates the wall-clock time used by the calling process.

返回处理器调用某个进程或函数所花费的时间,单位是1秒的CLOCKS_PER_SEC分之一,其中CLOCKS_PER_SEC在vs2008版本的time.h中的定义是1000,这样就使得种子变化的速度变快,降低随机数重复概率。



c/c++中时间函数和随机函数的总结 

*******************C++的随机函数和时间函数************

 

随机函数

 

一、C++中不能使用random()函数

     random函数不是ANSI C标准不能在gcc,vc等编译器下编译通过。 可改

用C++下的rand函数来实现。

     1、C++标准函数库提供一随机数生成器rand返回0RAND_MAX之间均

匀分布的伪随机整数。 RAND_MAX必须至少为32767。rand()函数不接受参数

默认以1为种子即起始值。 随机数生成器总是以相同的种子开始所以形成

的伪随机数列也相同失去了随机意义。但这样便于程序调试 

      2、C++中另一函数srand可以指定不同的数无符号整数变元为种

子。但是如果种子相同伪随机数列也相同。一个办法是让用户输入种子但是

仍然不理想。 

     3、 比较理想的是用变化的数比如时间来作为随机数生成器的种子。 time

的值每时每刻都不同。所以种子不同所以产生的随机数也不同。 

// C++随机函数VC program 

#include <stdio.h> 

#include <iostream> 

#include <time.h> 

using namespace std; 

#define MAX 100 

int main(int argc, char* argv[]) 

       srand( (unsigned)time( NULL ) );//srand()函数产生一个以当前时间开始的

随机种子.应该放在for等循环语句前面 不然要很长时间等待

for (int i=0;i<10;i++) 

cout<<rand()%MAX<<endl;//MAX为最大值其随机域为0~MAX-1

   return 0; 

 

二、rand()的用法 

     rand()不需要参数它会返回一个从0到最大随机数的任意整数最大随机

数的大小通常是固定的一个大整数。 这样如果你要产生0~10的10个整数

可以表达为 

int N = rand() % 11; 

     这样N的值就是一个0~10的随机数如果要产生1~10则是这样 

int N = 1 + rand() % 11; 

总结来说可以表示为 

a + rand() % n

     其中的a是起始值n是整数的范围。    a + rand() % (b-a+1) 就表示 之间的一个随机数

若要0~1的小数则可以先取得0~10的整数然后均除以10即可得到随机到十

分位的10个随机小数若要得到随机到百分位的随机小数则需要先得到0~100

的10个整数然后均除以100其它情况依

此类推。 

     通常rand()产生的随机数在每次运行的时候都是与上一次相同的这是有

意这样设计的是为了便于程序的调试。若要产生每次不同的随机数可以使用

srand( seed )函数进行随机化随着seed的不同就能够产生不同的随机数。 

     如大家所说还可以包含time.h头文件然后使用srand(time(0))来使用当

前时间使随机数发生器随机化这样就可以保证每两次运行时可以得到不同的随

机数序列(只要两次运行的间隔超过1秒)。 

 

 

函数名: random 

 

?功 能: 随机数发生器 

用 法: int random(int num); 

程序例: 

 

#include <stdlib.h> 

#include <stdio.h> 

#include <time.h> 

 

/* prints a random number in the range 0 to 99 */ 

int main(void) 

randomize(); 

printf("Random number in the 0-99 range: %d\n", random (100)); 

return 0; 

}

 

 

 

函数名: randomize 

功 能: 初始化随机数发生器 

用 法: void randomize(void); 

程序例: 

 

 

#include <stdlib.h> 

#include <stdio.h> 

#include <time.h> 

 

int main(void)  { 

int i; 

 

randomize(); 

printf("Ten random numbers from 0 to 99\n\n"); 

for(i=0; i<10; i++) 

printf("%d\n", rand() % 100); 

return 0; 

}

 

 

rand产生随机数 

相关函数 

srand 

 

表头文件 

#include<stdlib.h> 

 

定义函数 

int rand(void) 

 

函数说明 

rand()会返回一随机数值范围在0至RAND_MAX 间。在调用此函数产生随机数

前必须先利用srand()设好随机数种子如果未设随机数种子rand()在调用时

会自动设随机数种子为1。关于随机数种子请参考srand()。 

 

返回值 

返回0至RAND_MAX之间的随机数值RAND_MAX定义在stdlib.h其值为

2147483647。

 

 

范例 

/* 产生介于1 到10 间的随机数值此范例未设随机数种子完整的随机数产

生请参考 

srand*/ 

#include<stdlib.h> 

main() 

int i,j; 

for(i=0;i<10;i++) 

j=1+(int)(10.0*rand()/(RAND_MAX+1.0)); 

printf("%d ",j); 

}  } 

 

执行 

9 4 8 8 10 2 4 8 3 6 

9 4 8 8 10 2 4 8 3 6 

 

srand设置随机数种子 

 

相关函数 

 

rand 

 

表头文件 

#include<stdlib.h> 

 

定义函数 

void srand (unsigned int seed); 

 

函数说明 

srand()用来设置rand()产生随机数时的随机数种子。参数seed必须是个整数通

常可以利用geypid()或time(0)的返回值来当做seed。如果每次seed都设相同值

rand()所产生的随机数值每次就会一样。 

 

返回值 返回0至RAND_MAX之间的随机数值RAND_MAX定义在stdlib.h其

值为2147483647。 范例 /* 产生介于1 到10 间的随机数值此范例未设随机

数种子完整的随机数产生请参考 srand*/ #include<stdlib.h> main() { int i,j;

for(i=0;i<10;i++) { j=1+(int)(10.0*rand()/(RAND_MAX+1.0)); printf("%d ",j); } }

 

 

 

返回值 

 

范例 

/* 产生介于1 到10 间的随机数值此范例与执行结果可与rand参照*/ 

#include<time.h> 

#include<stdlib.h> 

main() 

int i,j; 

srand((int)time(0)); 

for(i=0;i<10;i++) 

j=1+(int)(10.0*rand()/(RAND_MAX+1.0)); 

printf(" %d ",j);  } 

 

执行 

5 8 8 8 10 2 10 8 9 9 

2 9 7 4 10 3 2 10 8 7

 

 

 

 

在指定的两个数之间产生随机数

 

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

 

//返回a和b之间的随机数,用时间做种子 

int rand_between_a_b(int a,int b)

{

     int c ,re,temp; 

     time_t t; 

     

     if(a < b)

     {

           temp = a;

           a = b;

           b = temp; 

     }

 

   c = a - b;

 

     srand((unsigned) time(&t)); //使用时间做种子数 

 

      re = b + (rand() % c);

     

     return re;

}

 

int main() 

    int re; 

      

     re = rand_between_a_b(35,98);

         printf("%d\n",re);

     getch();

    return 0;

}

 

注

srand()配置随机数种子。

srand((unsigned)time(NULL));产生伪随机数数列

rand()产生随机数

 

C库里的Rand函数用的是伪随机数生成算法你不种一个新种子进去生成的

随机数序列都是一样的。

 

伪随机的意思就是不随机种子相同的情况下等次数地获得的“随机”结果都

是一样的(函数嘛...)

为了让他真随机就得找个现成的随机量作初值

一般选时间作为srand的参数也就是seed

 

 

 

时间函数

 

一、获取日历时间

time_t是定义在time.h中的一个类型表示一个日历时间也就是从1970年1

月1日0时0分0秒到此时的秒数原型是

 typedef long time_t;        /* time value */

可以看出time_t其实是一个长整型由于长整型能表示的数值有限因此它能

表示的最迟时间是2038年1月18日19时14分07秒。

 

函数time可以获取当前日历时间时间time的定义

 time_t time(time_t *)

 

#include <iostream>

#include <time.h>

using namespace std;

int main(void)

{

 time_t nowtime;

 nowtime = time(NULL); //获取当前时间

 cout << nowtime << endl;

 

 return 0;

}

 输出结果:1268575163

 

 

二、获取本地时间 

time_t只是一个长整型不符合我们的使用习惯需要转换成本地时间就要用

到tm结构time.h中结构tm的原型是

struct tm {

        int tm_sec;     /* seconds after the minute - [0,59] */

        int tm_min;     /* minutes after the hour - [0,59] */

        int tm_hour;    /* hours since midnight - [0,23] */

        int tm_mday;    /* day of the month - [1,31] */

        int tm_mon;     /* months since January - [0,11] */

        int tm_year;    /* years since 1900 */

        int tm_wday;    /* days since Sunday - [0,6] */

        int tm_yday;    /* days since January 1 - [0,365] */

        int tm_isdst;   /* daylight savings time flag */

       };

 

 

可以看出这个机构定义了年、月、日、时、分、秒、星期、当年中的某一天、

夏令时。可以用这个结构很方便的显示时间。

 

用localtime获取当前系统时间该函数将一个time_t时间转换成tm结构表示的

时间函数原型

 struct tm * localtime(const time_t *)

使用gmtime函数获取格林尼治时间函数原型

 struct tm * gmtime(const time_t *)

 

 

 

为了方便显示时间定义了一个函数void dsptime(const struct tm *);

 

#include <iostream>

#include <time.h>

using namespace std;

void dsptime(const struct tm *); //输出时间。

 

int main(void)

{

 time_t nowtime;

 nowtime = time(NULL); //获取日历时间

 cout << nowtime << endl;  //输出nowtime

 

 struct tm *local,*gm;  local=localtime(&nowtime);  //获取当前系统时间

 dsptime(local); 

 gm=gmtime(&nowtime);  //获取格林尼治时间

 dsptime(gm);

  

 return 0;

}

void dsptime(const struct tm * ptm)

{

 char *pxq[]={"日","一","二","三","四","五","六"};

 cout << ptm->tm_year+1900 << "年" << ptm->tm_mon+1 << "月" <<

ptm->tm_mday << "日 " ;

 cout << ptm->tm_hour << ":" << ptm->tm_min << ":" << ptm->tm_sec <<" " ;

 cout << " 星期" <<pxq[ptm->tm_wday] << " 当年的第" << ptm->tm_yday << "天 "

<< endl;

}

 

输出结果

1268575163

2010年3月14日 21:59:23  星期日 当年的第72天

2010年3月14日 13:59:23  星期日 当年的第72天

 

 

 

三、输出时间

C/C++语言提供了用字符串格式表示时间的函数。

char * asctime(const struct tm *)

char * ctime(const time_t *)

这两个函数返回值都是一个表示时间的字符串区别在于传入的参数不同。

 

#include <iostream>

#include <time.h>

using namespace std;

int main(void)

{

 time_t nowtime;

 nowtime = time(NULL); //获取日历时间

 cout << nowtime << endl;  //输出nowtime

 

 struct tm *local;

 local=localtime(&nowtime);  //获取当前系统时间

 

 cout << asctime(local) ;

 cout << ctime(&nowtime) ;  return 0;

}

 

输出结果:

1268575163

Sun Mar 14 13:59:23 2010

Sun Mar 14 21:59:23 2010

 

 

 

四、计算时间间隔

可以通过difftime来计算两个时间的间隔可以精确到秒函数原型

 double difftime(time_t, time_t)

要想精确到毫秒就要使用clock函数了函数原型

 clock_t clock(void)

从定义可以看出clock返回一个clock_t类型这个类型也定义在time.h中原型

是 

 typedef long clock_t

clock_t也是一个长整型表示的是从程序开始运行到执行clock函数时所经过的

cpu时钟计时单元数。

 

输出结果:

请按任意键继续. . .

时间差3

Clock时间差3094

 

 

 

在time.h中定义了一个CLOCKS_PER_SEC

 /* Clock ticks macro - ANSI version */

 #define CLOCKS_PER_SEC  1000

表示1秒钟内有多少个时钟计时单元在标准C/C++中最小的计时单位是1毫

秒。

 

 

五、自定义时间格式

C/C++在time.h中提供了一个自定义时间格式的函数strftime函数原型

 size_t strftime(char *strDest, size_t maxsize, const char *format, const struct tm

*timeptr);

参数说明

 char *strDest用来存放格式化后的字符串缓存

 size_t maxsize指定最多可以输出的字符数

 const char *format格式化字符串

 const struct tm *timeptr要转换的时间。 

 

 

可使用的格式化字符串

%a 星期几的简写 

%A 星期几的全称 

%b 月分的简写 

%B 月份的全称 

%c 标准的日期的时间串 

%C 年份的后两位数字 

%d 十进制表示的每月的第几天 

%D 月/天/年 

%e 在两字符域中十进制表示的每月的第几天 

%F 年-月-日 

%g 年份的后两位数字使用基于周的年 

%G 年分使用基于周的年 

%h 简写的月份名 

%H 24小时制的小时 

%I 12小时制的小时

%j 十进制表示的每年的第几天 

%m 十进制表示的月份 

%M 十时制表示的分钟数 

%n 新行符 

%p 本地的AM或PM的等价显示 

%r 12小时的时间 

%R 显示小时和分钟hh:mm 

%S 十进制的秒数 

%t 水平制表符 

%T 显示时分秒hh:mm:ss 

%u 每周的第几天星期一为第一天 值从0到6星期一为0

%U 第年的第几周把星期日做为第一天值从0到53

%V 每年的第几周使用基于周的年 

%w 十进制表示的星期几值从0到6星期天为0

%W 每年的第几周把星期一做为第一天值从0到53 

%x 标准的日期串 

%X 标准的时间串 

%y 不带世纪的十进制年份值从0到99

%Y 带世纪部分的十进制年份 

%z%Z 时区名称如果不能得到时区名称则返回空字符。

%% 百分号

 

#include <iostream>

#include <time.h>

using namespace std; 

int main(void)

{

 time_t nowtime;

 nowtime = time(NULL); //获取日历时间

 cout << nowtime << endl;  //输出nowtime

 

 struct tm *local;

 local=localtime(&nowtime);  //获取当前系统时间

 

 char buf[80];

 strftime(buf,80,"格式化输出%Y-%m-%d %H:%M:%S",local);

 cout << buf << endl;

 

 return 0;

}

 输出结果

1268575163

格式化输出2010-03-14 21:59:23

 

 ***********C语言的时间函数************

Linux下c语言编程的时间函数详解默认分类 2010-03-12 10:41:35 阅读448 

 

/******************

* Linux时间函数    *

******************/

asctime将时间和日期以字符串格式表示; ===>传入UTC(struct tm)tmp返回

char*。

ctime将时间和日期以字符串格式表示; ===>传入(time_t)arg返回char*。

gettimeofday取得目前的时间; ===>传入(time_t)arg返回tvtz结构体传入

时间时区信息。

gmtime取得目前时间和日期; ===>传入(time_t)arg返回UTC(struct tm)tmp。

localtime取得当地目前时间和日期; ===>传入time_t返回当地(struct tm)tmp。

mktime将时间结构数据转换成经过的秒数; ===>把(struct tm)tmp转换为

UTC(time_t)arg。

settimeofday设置目前时间; ===>通过tvtz结构体传入时间时区信息。

time取得目前的时间; ===>非空参数或返回值接收(time_t)arg。

 

×××注1char*是字符串时间格式。如Sat Oct 28 02:10:06 2000。

×××注2time_t是time()的返回值类型(time_t)arg指从1970年到所指时间

的秒数。

×××注3struct tm为真实世界的表示时间方式(struct tm)tmp是指向tm的

  • 3
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值