Yuzhen's Blog

Yuzhen Qin

C++/STL 笔记 #1: 伪随机数生成和计时

29
2024-05-28

伪随机数生成

C 风格的 std::rand

rand() 返回一个范围 [0, RAND\_MAX] 内的伪随机整数值。保证 \text{RAND\_MAX} \ge 2^{15} - 1

在调用 rand() 前应该使用 srand() 设置种子。一般使用 time(0) 作为种子。

对于相同的种子,它必定产生相同的伪随机数数列。

在调用 srand() 前使用 rand(),则 rand() 表现为如同调用 srand(1) 后的行为。

一些 rand() 在随机性、分布和产生的序列周期上有严重缺陷。推荐用 C++11 的随机数生成设施替换 rand()

示例代码

#include <bits/stdc++.h>
using namespace std;

int main(void) {
    srand(time(0));

    for(int i = 1; i <= 10; i++)
        cout << rand() << ' ';

    cout << endl;

    return 0;
}

C++11 的随机数生成设施

std::random_device 生成一个 unsigned int 范围内的使用硬件熵源的非确定随机数。

std::mt19937 生成一个 uint_fast32_t 范围内的随机数。

std::mt19937_64 生成一个 uint_fast64_t 范围内的随机数。

示例代码

#include <bits/stdc++.h>
using namespace std;

int main(void) {
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dist(1, 100);

    // 生成一个 [1, 100] 范围内的 int
    for(int i = 1; i <= 10; i++)
        cout << dist(gen) << ' ';

    cout << endl;
    
    return 0;
}

计时

C 风格的 std::clock

示例代码

#include <bits/stdc++.h>
using namespace std;

int main(void) {
    clock_t start = clock();

    // ...

    clock_t end = clock();
    
    cout << "Time passed: " << (end - start) / CLOCKS_PER_SECOND << endl;
    
    return 0;
}

chrono

时钟

std::chrono::system_clock 为系统时钟,和一般和现实时钟对应。它可以不单调。

std::chrono::steady_clock 单调时钟,与现实时钟无关。

std::chrono::high_resolution_clock 拥有可用的最短计数周期的时钟。

duration

std::chrono::duration<存储类型, 一个 ratio 类模板>

类型 std::chrono::secondsstd::chrono::milliseconds 都是用整数保存的 duration

可以使用 chrono::duration_cast<类型> 来转换时间单位。

示例代码

#include <bits/stdc++.h>
using namespace std;

int main(void) {
    chrono::high_resolution_clock::time_point start = chrono::high_resolution_clock::now();
    
    // ...
    
    chrono::high_resolution_clock::time_point end = chrono::high_resolution_clock::now();
    
    chrono::high_resolution_clock::duration elapsed = end - start;
    
    cout << elapsed << "s" << endl; // double 类型,单位为秒
    cout << chrono::duration_cast(chrono::milliseconds)(elapsed) << "ms" << endl; // long long 类型,单位为毫秒
    
    return 0;
}

参考资料

  1. cppreference.com

  2. C++ std::chrono库使用指南 (实现C++ 获取日期,时间戳,计时等功能) - 知乎 (zhihu.com),作者:泡沫o0,创作声明:包含 AI 辅助创作