1. 程式人生 > >C++產生隨機數理解

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函式中,果然適當的理解比瞎實踐有用很多。