关于 std::random_shuffle 洗牌向量的说明
clarification regarding std::random_shuffle to shuffle the vector
我是 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);
只要我在 main.c
的开头调用以下函数,两者似乎都能正常工作
srand(time(NULL));
我还在网上找到了另一个解决方案,它使用 std::default_random_engine
auto rng = std::default_random_engine{};
std::shuffle(cards_vector.begin(), cards_vector.end(), rng);
但是,上面的解决方案总是return相同的洗牌,即使在 main 中调用随机种子也是如此。我不确定这是不是故意的。
如果有人能向我澄清这一点,我将不胜感激。
函数std::random_shuffle有两个重载。简而言之,这意味着您可以使用不同数量的参数调用相同的函数。
- 版本
std::random_shuffle(vector.begin(), vector.end());
调用由实现(编译器、操作系统、标准库等)定义的内部随机生成器。但是,它通常在内部使用 std::rand
.
来自文档:
The random number generator is implementation-defined, but the function std::rand is often used.
- 版本
std::random_shuffle(cards_vector.begin(), cards_vector.end(), myrandom);
使用显式随机生成器(您定义;即 myrandom
),它在内部调用 std::rand
.
函数std::rand (from C) generate a pseudo-random number。这意味着一旦你设置了 seed 它将生成(每次)相同的数字序列。换句话说,序列是确定性的取决于初始值(称为 seed)。
为了设置 std::rand
的种子(初始值),您需要调用接受种子作为参数的函数 std::srand
。
语句 srand(time(NULL));
是用 “随机”(实际上不是)种子初始化生成器的一个古老的常用技巧。事实上,函数 time(NULL)
returns 每次都应该不同的当前时间被调用。
因此,每次您的程序启动时,您都会为种子设置不同的数字,并且生成器 std::rand
每次都会产生不同的序列。
请注意: std::random_shuffle
是一个旧的 C++ 函数,它已被弃用。您确实应该使用它的替代品,即 std::shuffle
.
However, the solution above always return the same shuffle, even when the random seed is called in main. I am not sure whether that is intended or not.
这背后的原理同上。
在该示例中,您使用的是 另一个 (不同于 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()};
我是 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);
只要我在 main.c
的开头调用以下函数,两者似乎都能正常工作srand(time(NULL));
我还在网上找到了另一个解决方案,它使用 std::default_random_engine
auto rng = std::default_random_engine{};
std::shuffle(cards_vector.begin(), cards_vector.end(), rng);
但是,上面的解决方案总是return相同的洗牌,即使在 main 中调用随机种子也是如此。我不确定这是不是故意的。
如果有人能向我澄清这一点,我将不胜感激。
函数std::random_shuffle有两个重载。简而言之,这意味着您可以使用不同数量的参数调用相同的函数。
- 版本
std::random_shuffle(vector.begin(), vector.end());
调用由实现(编译器、操作系统、标准库等)定义的内部随机生成器。但是,它通常在内部使用std::rand
.
来自文档:
The random number generator is implementation-defined, but the function std::rand is often used.
- 版本
std::random_shuffle(cards_vector.begin(), cards_vector.end(), myrandom);
使用显式随机生成器(您定义;即myrandom
),它在内部调用std::rand
.
函数std::rand (from C) generate a pseudo-random number。这意味着一旦你设置了 seed 它将生成(每次)相同的数字序列。换句话说,序列是确定性的取决于初始值(称为 seed)。
为了设置 std::rand
的种子(初始值),您需要调用接受种子作为参数的函数 std::srand
。
语句 srand(time(NULL));
是用 “随机”(实际上不是)种子初始化生成器的一个古老的常用技巧。事实上,函数 time(NULL)
returns 每次都应该不同的当前时间被调用。
因此,每次您的程序启动时,您都会为种子设置不同的数字,并且生成器 std::rand
每次都会产生不同的序列。
请注意: std::random_shuffle
是一个旧的 C++ 函数,它已被弃用。您确实应该使用它的替代品,即 std::shuffle
.
However, the solution above always return the same shuffle, even when the random seed is called in main. I am not sure whether that is intended or not.
这背后的原理同上。
在该示例中,您使用的是 另一个 (不同于 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()};