【題目】
要求輸入一組數據,輸出的結果爲這組數據的隨機排列。
【解題思路】
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)。