1. c++ 库函数 rand() 以及 srand() 的使用
-
使用
rand()
和srand()
必须引入头文件#include <cstdlib>
-
基本用法:
randomnNum = rand()
,但实际是伪随机,该算法需要一个起始值,称为种子,以生成数字。如果没有给出一个种子,那么它将在每次运行时产生相同的数字流。要在每次运行程序时获得不同的随机数字流,则必须为随机数生成器提供一个种子以开始。在C++
中,这是通过调用srand()
函数完成的。 -
即如果单纯使用
rand()
函数而没有使用srand()
生成随机种子,那么每次运行都将生成同样的数字序列。#include <iostream> #include <cstdlib> using namespace std; int main() { for(int i = 0; i < 9; i++) cout << rand() << endl; return 0; }
-
运行结果:(重新编译运行也是这个结果)
-
在
rand()
被调用之前,srand()
函数要先被调用,并且srand()
在整个程序中仅被调用一次。#include <iostream> #include <cstdlib> using namespace std; int main() { srand(2); for(int i = 0; i < 9; i++) cout << rand() << endl; return 0; }
-
在程序得到随机数之前先将随机种子设置为2,得到了一种随机序列。
-
随机序列会根据随机种子的不同而变化,但如果输入相同的随机种子,则生成的随机序列将一样。
-
因此,只要每次生成随机数之前随机种子都事先变化即可,我们获取种子值的另一个常见做法是调用
time
函数,它是C++
标准库的一部分。 -
要使用
time
函数,要引入头文件#include <ctime>
。 -
time
函数返回从1970 年 1 月 1 日午夜
开始到现在逝去的秒数。 -
调用
time()
函数时必须给它传递一个参数 0。#include <iostream> #include <cstdlib> #include <ctime> using namespace std; int main() { srand(time(0)); for(int i = 0; i < 9; i++) cout << rand() << endl; return 0; }
-
这样,每次运行时生成的随机序列将不一样。
2. 公平洗牌算法
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
void swap(int *a, int *b) {
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
int main() {
int n = 54;
int arr[n];
for(int i = 0; i < n; i++)
arr[i] = i;
srand(time(0));
for(int i = n-1; i >= 0; i--) {
swap(arr[i], arr[rand()%(i+1)]);
}
for(int i = 0; i < 54; i++) {
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
- 一个公平的洗牌算法时:对于生成的排列,每一个元素都能等概率的出现在每一个位置。或者反过来,每一个位置都能等概率的放置每个元素。