程序生成随机数

随机数

  • [1. Qt](#1. Qt)
    • [1.1 qsrand() 和qrand()](#1.1 qsrand() 和qrand())
    • [1.2 QRandomGenerator 类](#1.2 QRandomGenerator 类)
  • [2. C语言](#2. C语言)
    • [2.1 使用 rand() 和 srand() 函数](#2.1 使用 rand() 和 srand() 函数)
    • [2.2 使用 <random.h> 库(C11 标准)](#2.2 使用 <random.h> 库(C11 标准))
  • [3. C++](#3. C++)
    • [3.1 使用 <cstdlib> 和 <ctime> 库(旧方法)](#3.1 使用 <cstdlib> 和 <ctime> 库(旧方法))
    • [3.2 使用 <random> 库(C++11 及以后推荐方法)](#3.2 使用 <random> 库(C++11 及以后推荐方法))
    • [3.3 生成浮点数随机数](#3.3 生成浮点数随机数)

1. Qt

1.1 qsrand() 和qrand()

通过qsrand() 和qrand()函数来生成随机数。随机数生成器本质上是按照特定算法生成一系列看似随机的数字。但实际上,这些数字是基于一个初始值(即种子)按照固定算法计算得出的。如果每次使用相同的种子,那么随机数生成器将产生相同的随机数序列。qsrand() 函数的作用就是为随机数生成器设置这个初始种子,从而影响后续生成的随机数序列。

  1. qsrand() 是 Qt 框架提供的一个用于初始化随机数生成器种子的函数,它在<QtCore/QRandomGenerator> (旧版本中是 <QtCore/QTime> 配合使用)相关的随机数生成操作中扮演着重要角色。
    该函数在 <QtCore/QRandomGenerator> 头文件(在旧版本中为 <QtCore/QCoreApplication> )中声明。这里的参数 seed 是一个无符号整数,作为随机数生成器的种子。
cpp 复制代码
void qsrand(uint seed);
  1. qrand() 函数用于生成具体的随机数。qrand() 函数用于生成伪随机整数。该函数生成的随机数范围是 [0, RAND_MAX],其中 RAND_MAX 是一个常量,表示随机数的最大值。RAND_MAX 的值在不同的系统和编译器中可能会有所不同,但在大多数系统中,RAND_MAX 被定义为 32767 (即 2^15 - 1)。这意味着 qrand() 函数生成的随机数是一个非负整数,其取值范围从 0 到 RAND_MAX。
cpp 复制代码
#include <QCoreApplication>
#include <QDebug>
#include <QTime>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 使用当前时间作为种子初始化随机数生成器
    qsrand(QTime::currentTime().msec());

    // 生成并输出10个随机整数
    for (int i = 0; i < 10; ++i) {
        int randomNumber = qrand();
        qDebug() << "生成的随机数: " << randomNumber;
    }

    return a.exec();
}

在这个例子中,使用 QTime::currentTime().msec() 作为种子,因为每毫秒的时间值通常是不同的,所以每次运行程序时,随机数生成器的种子不同,进而产生不同的随机数序列。qrand() 函数用于生成具体的随机数。

1.2 QRandomGenerator 类

不过,在现代 Qt(Qt 5.10 及以后版本)中,推荐使用 QRandomGenerator 类来生成随机数,它提供了更安全、更现代的随机数生成方式,而 qsrand() 和 qrand() 已被标记为过时。示例如下:

cpp 复制代码
#include <QCoreApplication>
#include <QDebug>
#include <QRandomGenerator>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 生成并输出10个随机整数
    for (int i = 0; i < 10; ++i) {
        quint32 randomNumber = QRandomGenerator::global()->generate();
        qDebug() << "生成的随机数: " << randomNumber;
    }

    return a.exec();
}

在这个示例中,QRandomGenerator::global()->generate() 用于生成一个无符号 32 位整数的随机数,并且不需要手动设置种子,QRandomGenerator 会自动处理种子的初始化,提供更好的随机性和安全性。
QRandomGenerator::global()->bounded(0, 101) 用于生成一个范围在 [0, 100] 的随机整数

  • 可重复性问题:如果需要复现相同的随机数序列,可使用固定的种子调用 qsrand()。但在大多数实际应用场景中,为了得到不同的随机数序列,通常会使用变化的值(如当前时间)作为种子。
  • 过时性:由于 qsrand() 和 qrand() 存在一些随机性和安全性方面的问题,在新的 Qt 项目中建议使用 QRandomGenerator 类来替代。

2. C语言

2.1 使用 rand() 和 srand() 函数

  1. rand() 函数:该函数会返回一个介于 0 到 RAND_MAX 之间的伪随机整数。RAND_MAX 是一个常量,其值至少为 32767,不同系统可能会有所不同。
  2. srand() 函数:此函数用于初始化随机数生成器的种子。若每次运行程序时种子相同,rand() 函数就会生成相同的随机数序列。所以,通常会使用当前时间作为种子,以确保每次运行程序时生成不同的随机数序列。
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    // 使用当前时间作为随机数生成器的种子
    srand(time(NULL));

    // 生成10个随机数
    for (int i = 0; i < 10; i++) {
        // 生成一个0到99之间的随机数
        int random_num = rand() % 100;
        printf("随机数 %d: %d\n", i + 1, random_num);
    }

    return 0;
}
  • srand(time(NULL)):time(NULL) 会返回当前的时间戳,将其作为 srand() 函数的参数,以此初始化随机数生成器的种子。
  • rand() % 100:rand() 函数生成一个随机整数,通过取模运算 % 100 可以将随机数的范围限制在 0 到 99 之间。

2.2 使用 <random.h> 库(C11 标准)

C11 标准引入了 <random.h> 库,该库提供了更强大、更灵活的随机数生成功能,能够生成不同分布的随机数,如均匀分布、正态分布等。

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <random>

int main() {
    // 创建一个随机数生成器
    struct random_data rd;
    char state[32];
    initstate_r(time(NULL), state, sizeof(state), &rd);

    // 生成10个0到99之间的随机数
    for (int i = 0; i < 10; i++) {
        int random_num;
        random_r(&rd, &random_num);
        random_num = random_num % 100;
        printf("随机数 %d: %d\n", i + 1, random_num);
    }

    return 0;
}
  • initstate_r():该函数用于初始化随机数生成器的状态,使用当前时间作为种子。
  • random_r():此函数会生成一个随机整数,同样通过取模运算将随机数的范围限制在 0 到 99 之间。
  • random_data 结构体是 <random.h> 头文件里定义的,这个头文件是 C11 标准引入的,用于实现更高级的随机数生成功能。random_data 结构体用于存储随机数生成器的内部状态信息。在使用 random_r 这类可重入的随机数生成函数时,就需要借助这个结构体来保存和管理随机数生成器的状态。之所以要有这样的结构体,是因为可重入函数要能在多线程环境下安全使用,每个线程得有自己独立的随机数生成器状态,避免不同线程之间的状态相互干扰。
  • 状态数组:char state[32]; 定义了一个字符数组 state,用于存储随机数生成器的状态信息。
  • 在多线程环境中使用 random_r 函数时,每个线程都需要有自己独立的 random_data 结构体变量,以此保证线程安全。

3. C++

3.1 使用 和 库(旧方法)

这种方法主要利用 rand() 函数生成随机数,同时使用 srand() 函数设置随机数种子。rand() 函数会返回一个介于 0 到 RAND_MAX 之间的伪随机整数,RAND_MAX 是一个常量,其值至少为 32767。为了让每次运行程序时生成不同的随机数序列,通常会使用 srand() 结合 time() 函数以当前时间作为种子。

cpp 复制代码
#include <iostream>
#include <cstdlib>
#include <ctime>

int main() {
    // 使用当前时间作为随机数种子
    std::srand(static_cast<unsigned int>(std::time(nullptr)));

    // 生成10个0到99之间的随机数
    for (int i = 0; i < 10; ++i) {
        int randomNumber = std::rand() % 100;
        std::cout << "随机数 " << i + 1 << ": " << randomNumber << std::endl;
    }

    return 0;
}
  • std::srand(static_cast(std::time(nullptr)));:使用当前时间作为随机数种子,确保每次运行程序时生成不同的随机数序列。
  • std::rand() % 100:生成一个 0 到 99 之间的随机数。

3.2 使用 库(C++11 及以后推荐方法)

库是 C++11 引入的,提供了更强大、更灵活且随机性更好的随机数生成功能。它包含了多种随机数引擎和分布类型,可以根据需求选择合适的引擎和分布来生成随机数。

cpp 复制代码
#include <iostream>
#include <random>

int main() {
    // 定义随机数引擎,这里使用默认的随机数引擎
    std::random_device rd;
    std::mt19937 gen(rd());

    // 定义分布类型,这里使用均匀分布,范围是0到99
    std::uniform_int_distribution<> dis(0, 99);

    // 生成10个随机数
    for (int i = 0; i < 10; ++i) {
        int randomNumber = dis(gen);
        std::cout << "随机数 " << i + 1 << ": " << randomNumber << std::endl;
    }

    return 0;
}
  • std::random_device rd;:创建一个 random_device 对象,它通常用于获取真正的随机数种子。
  • std::mt19937 gen(rd());:创建一个 mt19937 随机数引擎,并使用 random_device 生成的种子进行初始化。mt19937 是一个常用的梅森旋转算法随机数引擎,具有较好的随机性和性能。
  • std::uniform_int_distribution<> dis(0, 99);:创建一个均匀整数分布对象,指定随机数的范围为 0 到 99。
  • dis(gen):通过分布对象 dis 对随机数引擎 gen 进行采样,生成一个符合指定分布的随机数。

3.3 生成浮点数随机数

使用 库也可以方便地生成浮点数随机数,以下是一个生成 0 到 1 之间浮点数随机数的示例:

cpp 复制代码
#include <iostream>
#include <random>

int main() {
    std::random_device rd;
    std::mt19937 gen(rd());
    // 定义均匀浮点分布,范围是0到1
    std::uniform_real_distribution<> dis(0.0, 1.0);

    for (int i = 0; i < 10; ++i) {
        double randomNumber = dis(gen);
        std::cout << "随机浮点数 " << i + 1 << ": " << randomNumber << std::endl;
    }

    return 0;
}

这个示例与生成整数随机数的示例类似,只是使用了 std::uniform_real_distribution 来定义浮点数的均匀分布。

相关推荐
Bunury37 分钟前
element-plus添加暗黑模式
开发语言·前端·javascript
矛取矛求1 小时前
STL C++详解——priority_queue的使用和模拟实现 堆的使用
开发语言·c++
Non importa2 小时前
【C++】新手入门指南(下)
java·开发语言·c++·算法·学习方法
pp-周子晗(努力赶上课程进度版)2 小时前
【C++】特殊类的设计、单例模式以及Cpp类型转换
开发语言·c++
海洋与大气科学2 小时前
【matlab|python】矢量棍棒图应用场景和代码
开发语言·python·matlab
菜鸟学编程o3 小时前
C++:继承
开发语言·c++
wiseyao12193 小时前
c#操作excel
开发语言·c#·excel
努力努力再努力wz3 小时前
【c++深入系列】:万字string详解(附有sso优化版本的string模拟实现源码)
java·运维·c语言·开发语言·c++
hy____1233 小时前
类与对象(上)
开发语言·c++·算法
三次握手四次挥手3 小时前
基于Python+Pytest实现自动化测试(全栈实战指南)
开发语言·python·自动化·k8s·apache·pytest·代码规范