需要为数组生成随机排列序列。当然,我们可以使用专门为此目的设计的 STL 函数,但我想按如下方式手动完成:
问题> 根据代码,在我看来我们不应该将 std::default_random_engine generator;
放在循环中。一般来说,这是真的吗?
// uniform_int_distribution
#include <iostream>
#include <random>
#include <utility>
void test1() // random result
{
int p[10]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::default_random_engine generator;
for (int i=0; i<=9; ++i) {
std::uniform_int_distribution<int> distribution(i,9);
int index = distribution(generator);
std::swap(p[index], p[i]);
std::cout << i << ": " << p[i] << std::endl;
}
}
void test2() // NOT random
{
int p[10]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i=0; i<=9; ++i) {
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(i,9);
int index = distribution(generator);
std::swap(p[index], p[i]);
std::cout << i << ": " << p[i] << std::endl;
}
}
int main()
{
test1();
std::cout << "*****************" << std::endl;
test2();
return 0;
}
/* output
0: 0
1: 2
2: 8
3: 6
4: 7
5: 3
6: 5
7: 9
8: 4
9: 1
*****************
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9
*/
最佳答案
随机生成器引擎在进入作用域时被播种。
在您的第一个函数中,您具有以下基本结构:
void test1() // random result
{
std::default_random_engine generator;
for (int i=0; i<=9; ++i) {
// ...
}
}
当您输入 test1()
时,随机数生成器会被播种。每次调用 test1()
时,您都会得到一个新的生成器,并且很可能是相同的排列。该生成器的范围是从它的声明点到 test1()
的右大括号。
在你的第二个函数中,你有这个替代结构:
void test2() // NOT random
{
for (int i=0; i<=9; ++i) {
std::default_random_engine generator;
// ...
}
}
此生成器在循环的每次迭代开始时进入范围,并在每次迭代结束时(就在循环增量之前)离开范围。我相信,这将在每次迭代中为您提供相同的随机数序列。
如果你想要一个随机序列被播种一次,你只需要有一个生成器实例。要么将其设为全局变量,要么将对生成器的引用作为参数传递给您的函数。
关于c++ - 调用 `std::default_random_engine generator` 的正确位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20590956/