C++中隨機數和不重復的隨機數


隨機數

    int rand ();

    rand函數返回一個0-32767之間的一個偽隨機整數,32767可以由宏RAND_MAX表示,該函數需要頭文件<stdlib.h>。

    常用的是如何生成一個范圍內的隨機數,例如想生成0-100之間的隨機數,那么我們可以編寫如下語句:

 1 #include <stdlib.h>
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 void RAND(int max, int min, int n)
 7 {
 8     for(int i = 0; i < n; ++i)
 9     {
10         int u = (double)rand() / (RAND_MAX + 1) * (max - min) + min; 
11         cout << u << " ";
12     }
13 }

      第10行是關鍵,rand()生成一個隨機數,通過一系列簡單的數學計算將隨機范圍變到min與max之間。需要注意的是,將rand轉化為double類型之后是保證在做除法時得到有效地數字,最后因為u聲明為int類型,最后可以保證得到的是整數序列。參數n是隨機數的個數。生成0-100的10個隨機數的語句為

RAND(100, 1, 10);

      結果如圖,但是這樣每次生成的隨機數都相同,因此我們需要一種方法來生成不同的隨機數。srand()函數用以設定隨機數種子,我們知道隨機數的產生實際上是從一個偽隨機數列中取值,我們通過設置隨機數種子,即可以從該偽隨機數列的不同位置取值,顯示出來就達到了更新隨機數的目的。

void srand( unsigned int seed );

里面接受一個int數值,一般采取的方式是根據當前系統時間來產生一個數值,用該數值來作為隨機數種子,需要頭文件<time.h>。

1 void RAND(int max, int min, int n)
2 {
3     srand(time(NULL));
4     for (int i = 0; i < n; i++)
5     {
6         int u = (double)rand() / (RAND_MAX + 1) * (max - min) + min;
7         cout << u << " ";
8     }
9 }

第三行便更新了隨機數種子,得到結果為 ,可以看出隨機數有了更新。

不重復隨機數

     從第二次運行的結果來看,我們發現產生了兩個90,如果我們想要避免這種情況,即產生的隨機數不會重復,那么該如何進行代碼的編寫?

     最初的思想是每生成一個隨機數,便於前面的所有隨機數進行比較,如果有重復,則舍去不要,重新選取。但該方法十分費時,並且在數據量巨大的並且有一定限制的時候,會引發巨大問題。例如要生成10000個隨機數,范圍是0-9999,且不能重復,那么最后幾個隨機數有可能需要相當長的時間才能篩選出來。

    下面我們從另外一個角度來思考,假設我們已經由一個數組長度為10000的數組,里面分別存儲了數據0-9999,我現在的做法是想辦法讓10000個數進行隨機排列,便得到了這樣一個隨機數列,如果我只要其中的100個數,那么從前面取出100個就好。這里利用algorithm.h里面的一個函數,,來進行簡單處理。

template<class RandomAccessIterator>  
    void random_shuffle(
      RandomAccessIterator _First, 
      RandomAccessIterator _Last
);

這個函數操作的對象是容器的迭代器,即我們需要將存儲數據從數組變為容器就好了,下面代碼實現一下:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <vector>
 4 
 5 using namespace std;
 6 
 7 void randperm(int Num)
 8 {
 9     vector<int> temp;
10     for (int i = 0; i < Num; ++i)
11     {
12         temp.push_back(i + 1);
13     }
14 
15     random_shuffle(temp.begin(), temp.end());
16 
17     for (int i = 0; i < temp.size(); i++)
18     {
19         cout << temp[i] << " ";
20     }
21 }
22 
23 cout << endl;

給函數傳10為,參數,即生成一個從1-10的不重復隨機數,結果為:

 


上面的方式只是一種,還有很多方式用以產生不重復隨機數,有興趣的朋友可以參考一下下面的連接:

http://www.hoopercao.com/2011/01/23/%E7%94%9F%E6%88%90%E4%B8%8D%E9%87%8D%E5%A4%8D%E7%9A%84%E9%9A%8F%E6%9C%BA%E6%95%B0%E7%9A%84%E6%96%B9%E6%B3%95/

http://www.cnblogs.com/afarmer/archive/2011/05/01/2033715.html

http://www.cnblogs.com/zuisanlang/archive/2011/12/09/2282960.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM