C++產生隨機數理解
rand:
rand()函式需要用到標頭檔案#include<cstdlib>,根據種子值返回一個偽隨機函式,為什麼說是偽隨機,是因為程式都是根據一定的演算法來實現的,在不設定srand時,預設為呼叫的是srand(1),由於每次都是一樣的種子值,使得每次執行產生的結果都是相同的。
#include<iostream> #include<cstdlib> using namespace std; int main() { int Rand[10]; for(int i=0;i<10;i++) Rand[i]=rand();for (int i = 0; i<10; i++) cout<<Rand[i]<<" "; system("pause"); }
每次執行結果都是相同:
srand:
通過修改種子值srand可以使得每次產生的隨機數不同,但是還是會有一定的規律,為了產生更加隨機的隨機數,一般是採用時間作為種子數
srand((unsigned)time(NULL));//需要標頭檔案#include<ctime>
修改後的程式碼如下:
#include<iostream> #include<cstdlib> #include<ctime> using namespace std; int main() { int Rand[10]; srand((unsigned)time(NULL)); for(int i=0;i<10;i++) Rand[i]=rand(); for (int i = 0; i<10; i++) cout<<Rand[i]<<" "; system("pause"); }
可以發現每次執行的結果都不一樣了。
通式:
如果要去一定範圍內的值,則要用到通式k=x+rand()%(y-x+1),k即為所求範圍內隨機生成的數,rand()%a的結果最大為a-1。
整數例子:
[0,10]:rand()%11
[1,11]:1+rand()%11
(0,10):1+rand()%9
浮點數例子:
[0.0,1.0]=(rand()%10)*0.1
函式:
上述例子產生隨機數都是在main函式中,但是有時候我們希望把產生隨機數的函式封裝起來,適當地呼叫,但是錯誤的編寫就會導致每次出來的隨機數都是相同的。
錯誤例子
#include<iostream> #include<cstdlib> #include<ctime> using namespace std; int GetRand() { int Rand; srand((unsigned)time(NULL)); Rand = rand()%10; return Rand; } int main() { int Rand[10]; for(int i=0;i<10;i++) Rand[i]=GetRand(); for (int i = 0; i<10; i++) cout<<Rand[i]<<" "; system("pause"); }
正確例子:
#include<iostream> #include<cstdlib> #include<ctime> using namespace std; int GetRand() { int Rand; Rand = rand()%10; return Rand; } int main() { int Rand[10]; srand((unsigned)time(NULL)); for(int i=0;i<10;i++) Rand[i]=GetRand(); for (int i = 0; i<10; i++) cout<<Rand[i]<<" "; system("pause"); }
產生這個的原因很簡單,錯誤的例子中每一次進入for迴圈都是重新設定了一次種子值,由於程式執行速度十分快,srand是以秒作為時間單位,這就是相當於每一次進入迴圈的重新設定了相同的種子值,所以得出的結果也就是相同了。
而在正確的例子中,把設定種子值呼叫在for之前,也就相當於把後面的十次迴圈按照第一次設定的種子值產生序列,自然值也就不同。
處理方法並不唯一,另一種處理方式是利用類結構體:
class RandomNumber { public: RandomNumber() { srand((unsigned)time(NULL)); } int GetRand() { int RandNumber; RandNumber = rand()%301; return RandNumber; } };
通過建構函式在建立類時設定好種子值,後序呼叫自然也會按照該種子值設定好的序列來進行。
總結:
一般情況下,在程式中只要寫一次srand((unsigned)time(NULL))即可,需要注意該語句是否處在迴圈中。
PS:以前不懂都是把srand的語句瞎換位置,不用就把語句直接寫mian函式中,果然適當的理解比瞎實踐有用很多。