c++ - 调用 `std::default_random_engine generator` 的正确位置

标签 c++

需要为数组生成随机排列序列。当然,我们可以使用专门为此目的设计的 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/

相关文章:

c++ - 如何删除作为 C++ union 的成员变量的字符串对象?

c++ - 调试 CPU 缓存

c++ - QML 中的设置值保存在哪里?

android - Android NDK printf 输出在哪里?

c++ - 如何从 DLL 中写入浮点值?

c++ - 托管 DirectX 作为起点

c++ - 包含由换行符分隔的单词的文件和 C++ 中这些单词的字符串 vector 是否具有相同的大小?

c++ - push_back 新元素到 vector

c++ - 调用 Void Pointer Buffer 参数会引发运行时错误

c++ - 在 C++ 中获取耗时仅几秒钟