洗牌算法和隨機數生成

【題目】

要求輸入一組數據,輸出的結果爲這組數據的隨機排列。

【解題思路】

1.      調用頭文件algorithms中的random_shuffle函數。該函數的本質就是生成隨機位置,不斷交換,使得數據重新排列。

2.      產生隨機數,結合swap函數實現數組的重新排列。

【代碼】

#include <iostream>
#include <vector>
#include <algorithm>
#include <time.h>
#include <stdlib.h>

using namespace std;

vector<int> shuffle(vector<int> &A){
    int n = A.size();
    vector<int> res(A);
    for (int i = n-1; i>= 0; --i) {
        srand((unsigned int)time(NULL));
        int loc = rand()%(i+1);
        if (loc != i) {
            swap(res[i], res[loc]);
        }
    }
    return res;
}
int main()
{
    int n = 10;
    vector<int> A;
    for (int i = 0; i < n; ++i)
        A.push_back(i);
    vector<int> A1(A);
    cout << "origin" << endl;
    for (int i = 0; i < n; ++i)
        cout << A[i] << " ";
    for (int i = 0; i < 3; ++i) {
        //通過生成隨機位置並交換實現洗牌
        cout << "\nshuffle" << endl;
        vector<int> res = shuffle(A);
        for (int i = 0; i < n; ++i)
            cout << res[i] << " ";
        //調用random_shuffle()函數實現洗牌
        cout << "\nrandom_shuffle" << endl;
        random_shuffle(A1.begin(), A1.end());
        for (int i = 0; i < n; ++i)
            cout << A1[i] << " ";
    }
    return 0;
}

【隨機數生成函數】

1.      rand()

rand()爲隨機數發生器,包含在頭文件stdlib.h中,可以產生隨機數,但是這不是真正意義上的隨機數,是一個僞隨機數,是以一個數(可以稱爲種子)爲基準,以某個遞推公式推算出來的一系列數,當這系列數很大的時候,就符合正態公佈,從而相當於產生了隨機數,但這不是真正的隨機數,當計算機正常開機後,這個種子的值是定了的,除非你破壞了系統。

用戶未設定隨機數種子時,系統默認的隨機數種子爲1。

rand()產生的是僞隨機數字,每次執行時是相同的;若要不同,用函數srand()初始化它。

2.      srand()

srand()爲初始化隨機數發生器,包含在頭文件stdlib.h中,使用時參數爲種子(無符號整數),用來設置rand()產生隨機數時的隨機數種子。參數seed必須是個整數,如果每次seed都設相同值,rand()所產生的隨機數值每次就會一樣。

使用當前時鐘作爲隨機數種子,因爲每一次運行程序的時間是不同的,因此可以產生不同的隨機數種子,進而得到不同的隨機數。具體用法爲srand((unsigned int) time(NULL))。

如果不使用srand()初始化隨機數發生器,程序運行兩次得到的結果如下:


使用srand()初始化隨機數發生器後,程序運行兩次得到的結果如下:


產生一定範圍隨機數的通用表示公式

要取得[a,b)的隨機整數,使用(rand()% (b-a))+ a;

要取得[a,b]的隨機整數,使用(rand()% (b-a+1))+ a;

要取得(a,b]的隨機整數,使用(rand()% (b-a))+ a + 1;

通用公式:a + rand() % n;其中的a是起始值,n是整數的範圍。

要取得a到b之間的隨機整數,另一種表示:a + (int)b * rand() / (RAND_MAX + 1)。

要取得0~1之間的浮點數,可以使用rand() / double(RAND_MAX)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章