我是C++的工程师,想澄清一下。我有一个字符串向量,必须随机打乱它。
我正在努力了解之间的区别
std::random_shuffle(vector.begin(), vector.end());
int myrandom(int i) {
return std::rand() % i;
}
std::random_shuffle(cards_vector.begin(), cards_vector.end(), myrandom);
只要我在主.c 开始时调用以下函数,两者似乎都能正常工作
srand(time(NULL));
我还在互联网上找到了另一个解决方案,它使用std::default_random_engine
auto rng = std::default_random_engine{};
std::shuffle(cards_vector.begin(), cards_vector.end(), rng);
然而,即使在main中调用了随机种子,上面的解决方案也总是返回相同的shuffle。我不确定这是否有意。
如果有人能向我澄清这一点,我将不胜感激。
std::random_shuffle(vector.begin(), vector.end());
版本调用由实现(编译器、操作系统、标准库等(定义的内部随机生成器。然而,它通常在内部使用std::rand
来自文档:
随机数生成器是实现定义的,但经常使用函数std::rand。
- 版本
std::random_shuffle(cards_vector.begin(), cards_vector.end(), myrandom);
使用一个显式随机生成器(您定义的,即myrandom
(,该生成器在内部调用std::rand
函数std::rand(来自C(生成一个伪随机数。这意味着,一旦设置了种子,它将(每次(生成相同的数字序列。换句话说,序列是确定性的,取决于初始值(称为种子(。
为了设置std::rand
的种子(初始值(,您需要调用函数std::srand
,该函数接受种子作为参数。
语句CCD_ 8是用";"随机">(实际上不是(种子。实际上,函数time(NULL)
返回当前时间,该时间应该在每次调用时都不同。
因此,每次程序启动时,您都会用不同的数字设置种子,生成器std::rand
每次都会产生一个不同的序列。
请注意:std::random_shuffle
是一个旧的C++函数,它已被弃用。您确实应该使用它的替代品,即std::shuffle
。
然而,上面的解决方案总是返回相同的shuffle,即使在main中调用随机种子也是如此。我不确定这是否有意。
这背后的原理与上述相同。
在该示例中,您正在使用另一个(不同于std::rand
(伪随机数生成器,即std::default_random_engine{}
。此生成器默认使用默认种子进行初始化。
如果你想为不同的应用程序运行生成不同的结果,你需要用一个种子初始化生成器,这个种子意味着每次应用程序启动时都是不同的。
更正确的代码是:
#include <algorithm>
#include <chrono>
#include <random>
// ...
auto rng = std::default_random_engine{std::chrono::system_clock::now().time_since_epoch().count()};