gpt4 book ai didi

c++ - 在 C++03 和 C++14 的代码中进行简单随机改组的最佳做法是什么?

转载 作者:太空狗 更新时间:2023-10-29 20:12:25 25 4
gpt4 key购买 nike

背景:我正在为一个简单的游戏洗牌 vector 的元素。应该可以通过传递相同的整数种子来重新玩同一个游戏——反之亦然,不同的种子应该产生不同的游戏。密码安全性(或任何严格性)不是设计目标;代码的简洁性是一个设计目标。

C++98/C++03引入了std::random_shuffle,这样使用:

int seed = ...;
std::srand(seed); // caveat, see below

std::vector<int> deck = ...;
std::random_shuffle(deck.begin(), deck.end());

但是,从 C++14 开始,random_shuffle 已被弃用(来源:N3924)。 C++14 洗牌的方式是

int seed = ...;

std::vector<int> deck = ...;
std::shuffle(deck.begin(), deck.end(), std::mt19937(seed));

以下是每种方法的缺点:

  • srand/random_shuffle 方法在 C++14 中已弃用,因此我们不应该使用它。

  • 在某些实现中,random_shuffle 似乎没有从 srand 中获取种子,即,使用不同的值播种不会产生不同的输出! (Linux 上的 libstdc++ 没有这个问题,但 OSX 10.9.5 上的 Xcode 有。)

  • shuffle/mt19937 方式不是 C++03 的一部分,因此我们不能使用它。

  • shuffle/mt19937 方法似乎要求我们将种子一直向下传递到牌组洗牌代码中。对于我的应用程序,我更愿意通过诸如隐藏全局变量的 srand 之类的机制“设置它并忘记它”,而不是必须定义我自己的 类型的全局 PRNG mt19937。换句话说:我不想被 PRNG 细节打扰,我只想打乱我的 vector !

  • 有点担心线程安全(能够从不同线程同时洗牌两副不同的牌组),但显然不会同时担心线程安全和“可播种性” .将线程安全视为“可有可无”。

我想到的第一个候选人是:

  • 硬着头皮将 int seed 一直传递到洗牌代码中(避免使用全局变量)

  • 使用 #if __cplusplus >= 20110000 来使用 random_shuffle pre-C++11 和 shuffle post-C++11

  • 要解决 OSX 上的 srand“错误”,请使用带有一些复杂仿函数的 random_shuffle 的三参数版本...这听起来很难看

第二个候选人是:

  • 拧紧C++03;只是放弃对任何不提供开箱即用的 std::shufflestd::mt19937
  • 的实现的支持

但是有什么好的方法可以解决这个问题吗?我知道这是一个没有人会遇到的问题,除非他们的程序是一个玩具程序;但肯定有 数百 的玩具程序遇到了这个问题!

最佳答案

首先,开发一个所需的界​​面。它应该向用户隐藏任何平台/编译器细节,但为您提供实现所需的所有数据。编写具有所需用法的单元测试。像这样:

int seed = ...;
std::vector<int> deck = ...;
my_shuffle(deck.begin(), deck.end(), seed);

然后实现

template< typename IteratorType >
void my_shuffle( IteratorType first, IteratorType last,
int seed = some_default_seed_maybe )
{
#ifdef MACOS_FOUND
// Mac solution
#elif __cplusplus >= 201103L
// C++11 solution
#else
// fallback
}

看起来够干净吗?

同时检查:How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor?

关于c++ - 在 C++03 和 C++14 的代码中进行简单随机改组的最佳做法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27791474/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com