关于std的澄清::random_shuffle来搅乱向量



我是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有两个重载。简而言之,这意味着您可以用不同数量的参数调用同一个函数。
  • 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()};
    

相关内容

  • 没有找到相关文章

最新更新