1.随机数生成
1.1 随机数发生器 rand()
包含在头文件<stdlib.h>
中的函数rand()
可生成一个随机数,其有以下特点:
- 其形式
int rand(void)
内部使用线性同余法产生随机数,是“伪随机数”,只不过是因为其周期特别长,所以有一定的范围里可看成是随机的 - 它生成一个闭区间[0,RAND_MAX]内的均匀随机整数,即该区间内每个整数被随机获 取的概率相同,其中
RAND_MAX
至少为 32767 ( 2 1 5 − 1 ) 32767(2^15-1) 32767(215−1),不同环境可能不同。 - 如果需要产生
[
0
,
n
]
[0,n]
[0,n]之间的随机数,若
n
<
R
A
N
D
M
A
X
n < RAND_MAX
n<RANDMAX,则可以使用
rand() % n
,但是不一定是均匀的 - 若 n > R A N D M A X n > RAND_MAX n>RANDMAX,则可以使用 r a n d ( ) / R A N D M A X ∗ n rand() / RAND_MAX * n rand()/RANDMAX∗n,即先除以 RAND_MAX进行归一化,再乘以n进行四舍五入,但是存在误差。
1.2 随机数种子
- rand()产生的是假随机数字,每次执行时是相同的。若要不同,以不同的值来初始化它.初始化的函数就是 srand()。
- 包含在头文件
<stdlib.h>
中的函数srand(int)
初始化随机数种子,配合rand()
使用。 - 需要随机数的程序在最开始时一般会执行一次srand(time(NULL)),目的是初始
化“随机数种子”。而种子不同,rand()每次产生的随机数序列就会不同。 - 如果不调用srand而直接使用rand( ),相当于调用过一次srand(1),因此 程序每次执行时,将得到同一套随机数
- 其中在
<time.h>
中的time()
函数将会返回自UTC时间1970年1月1日0点以来经 过的“秒数”,每秒变化一次,将其作为srand()
的参数,则会随机化不同的种子。
2.时间记录
2.1 clock()计时函数
在<time.h>
中的clock()函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数,在MSDN中称之为挂钟时间(wal-clock)。
#ifndef _CLOCK_T_DEFINED
typedef long clock_t;
#define _CLOCK_T_DEFINED
#endif
clock_t clock(void); // 返回长整型
2.2 每秒的时钟单元数
在<time.h>
中还定义了一个常量CLOCKS_PER_SEC
,表示一秒钟的时钟计时单元数,
#define CLOCK_PER_SEC ((clock_t)1000)
#define CLK_TCK CLOCK_PER_SEC
所以clock() / CLOCKS_PER_SEC
就是经过的秒数。
//计算一段程序运行的时间
#include<iostream>
#include<ctime>
using namespace std;
int main()
{
clock_t startTime,endTime;
startTime = clock();//计时开始
for (int i = 0; i < 2147483640; i++)
{
i++;
}
endTime = clock();//计时结束
cout << "The run time is: " <<(double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
system("pause");
return 0;
}
3.程序正确性证明
我们下面写一段程序来验证C++中STL的sort()
排序的正确性以及时间。
#include<iostream>
#include<stdio.h>
#include<vector>
#include<stdlib.h>
#include<ctime>
#include<cassert>
#include<algorithm>
using namespace std;
const int maxn = 1e+6; // 生成的随机数数目
void fill_random_int(vector<int>& v, int cnt) {
// 生成cnt个随机数
for (int i = 0; i < cnt; i++)
v.push_back(rand());
}
void test_sort(vector<int>& v) {
// 测试排序函数
sort(v.begin(), v.end());
for (int i = 0; i < v.size() - 1; i++) {
assert(v[i] <= v[i + 1]);
}
}
int main() {
vector<int> v;
int time1 = clock();
fill_random_int(v, maxn);
int time2 = clock();
printf("随机数生成时间%.2fs\n", (double)(time2 - time1) / CLOCKS_PER_SEC);
test_sort(v);
int time3 = clock();
printf("测试时间%.2fs\n", (double)(time3 - time2) / CLOCKS_PER_SEC);
return 0;
}
其中,我们用到动态断言assert(条件)
,当条件为真时无变化,当条件为假时终止程序并给出错误提示。