1. 程式人生 > >用時間做種子生成隨機數

用時間做種子生成隨機數

我們知道rand()函式可以生成隨機數,其實是在種子的基礎上做某種變換並返回生成的隨機數。在預設情況下,種子是1。寫一個小程式測試一下。

[cpp] view plaincopyprint?
  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內呼叫多次,那麼產生的資料是相同的。可以用下面的程式碼進行測試。

[cpp] view plaincopyprint?
  1. for
     (int i = 0;i<1000;++i)  
  2.     std::cout<<randSelectQuestion(1,1000)<<'/t';  
[cpp] view plaincopyprint?
  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的