在C++中,std::random_device
是一个非确定性随机数生成器,它通常用于产生高质量的随机种子。std::mt19937
是一个Mersenne Twister算法实现的伪随机数生成器,它需要一个种子来初始化。
首先创建了一个 std::random_device
对象 rd
,然后通过调用 rd()
来获取一个随机数,这个随机数被用作 std::mt19937
伪随机数生成器 gen
的种子。这样,每次程序运行时,由于 std::random_device
生成的是非确定性的随机数,gen
也会得到不同的种子,从而生成不同的随机数序列。
下面是一个从0到九随机数的代码:
#include <iostream>
#include <random>
int main() {
// 创建一个随机引擎
std::random_device rd;
std::mt19937 gen(rd());
// 创建一个分布对象,指定范围[0, 9]和整数类型
std::uniform_int_distribution<> dis(0, 9);
// 生成随机数
int random_num = dis(gen);
std::cout << "Random number in range [0, 9]: " << random_num << std::endl;
return 0;
}
我在解决随机化问题的时候看到有博主写的随机化代码只用了一行,如下:
int m = rand() % (r - p + 1) + p;
对于这段代码的解释如下:
这行代码是C++中用来生成一个随机整数m
的,该整数位于闭区间[p, r]
内。这里使用了C++标准库中的rand()
函数来生成一个随机整数,并通过模运算(%
)和加法来将这个随机整数映射到所需的区间。
下面是这行代码的逐步解释:
-
rand()
:这是C++标准库中的一个函数,用于生成一个伪随机整数。通常情况下,这个整数在0
到RAND_MAX
(RAND_MAX
是rand()
函数可能返回的最大值,通常是32767
)之间。 -
rand() % (r - p + 1)
:这里使用模运算(%
)将rand()
返回的随机数限制在0
到r - p
之间。加上1
是为了确保区间是闭区间,即包括r
。 -
+ p
:最后,通过加上p
,将随机数的范围从[0, r - p]
映射到[p, r]
。
综上所述,int m = rand() % (r - p + 1) + p;
这行代码会生成一个位于闭区间[p, r]
内的随机整数,并将其赋值给变量m
。
需要注意的是,rand()
函数生成的随机数质量并不高,对于需要高质量随机数的应用(如密码学或模拟),建议使用C++11引入的<random>
库中的随机数生成器。此外,rand()
函数每次运行程序时生成的随机数序列是相同的(除非在程序开始时用srand()
函数设置了不同的种子),因此如果需要每次运行程序时都生成不同的随机数序列,也需要在使用rand()
之前设置种子。
关于模运算这个 我也需要理解一下(ps,数学我是真菜呀)
嗯,好像懂了。对于“%”这个的意思就是取余数,那么对于大于r-p+1的数:
能整除的话,就是0(这里也就是为什么要加一的原因了,如果仅仅只是r-p的话 那么最终数据,就不会得出r-p,而是在这个基础上-1,即r-p-1,所以这个加1不能漏掉);
不能整除的话,就是得出一个余数嘛,不是整除不会等于0,那么该数也是落在[1,r-p](注意是闭区间,理由上边解释了)
真是巧妙 ,这样子就能很好得出需要的范围内的随机数了。
这两种方法的其区别是前者更高质量 应该应需要而选择 我仅是为了解决蓝桥杯算法题的问题 用后者更为方便一些。