如何使用< random>替换rand()? [英] How to use <random> to replace rand()?

查看:143
本文介绍了如何使用< random>替换rand()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ 11引入了标头<random>,其中包含用于随机数引擎和随机分布的声明.太好了-是时候替换rand()的那些用法了,这在各种方式上通常都是有问题的.但是,如何替换似乎远非如此

C++11 introduced the header <random> with declarations for random number engines and random distributions. That's great - time to replace those uses of rand() which is often problematic in various ways. However, it seems far from obvious how to replace

srand(n);
// ...
int r = rand();

根据声明,似乎可以构建如下所示的统一分布:

Based on the declarations it seems a uniform distribution can be built something like this:

std::default_random_engine engine;
engine.seed(n);
std::uniform_int_distribution<> distribution;
auto rand = [&](){ return distribution(engine); }

这种方法似乎相当复杂,与使用srand()rand()不同,我肯定不会记得这种方法.我知道 N4531 ,但即使如此,参与其中.

This approach seems rather involved and is surely something I won't remember unlike the use of srand() and rand(). I'm aware of N4531 but even that still seems to be quite involved.

是否有一种相当简单的方法来替换srand()rand()?

Is there a reasonably simple way to replace srand() and rand()?

推荐答案

是否有一种相当简单的方法来替换srand()和rand()?

Is there a reasonably simple way to replace srand() and rand()?

完全公开:我不喜欢rand().不好,很容易被滥用.

Full disclosure: I don't like rand(). It's bad, and it's very easily abused.

C ++ 11随机库填补了很长一段时间以来一直缺乏的空白.高质量随机库的问题在于它们通常很难使用. C ++ 11 <random>库在这方面代表了巨大的进步.几行代码,我有一个很好的生成器,其表现非常好,并且可以轻松地从许多不同的分布生成随机变量.

The C++11 random library fills in a void that has been lacking for a long, long time. The problem with high quality random libraries is that they're oftentimes hard to use. The C++11 <random> library represents a huge step forward in this regard. A few lines of code and I have a very nice generator that behaves very nicely and that easily generates random variates from many different distributions.


鉴于上述情况,我对您的回答有点异端.如果rand()足以满足您的需求,请使用它.与rand()一样糟糕(而且很糟糕),将其删除将代表C语言的重大突破.只需确保rand()的缺点确实足以满足您的需求.

Given the above, my answer to you is a bit heretical. If rand() is good enough for your needs, use it. As bad as rand() is (and it is bad), removing it would represent a huge break with the C language. Just make sure that the badness of rand() truly is good enough for your needs.

C ++ 14未弃用rand();它仅弃用C ++库中使用rand()的函数.尽管C ++ 17可能会弃用rand(),但它不会删除它.这意味着rand()消失之前还有几年.当C ++委员会最终确实从C ++标准库中删除rand()时,您将退休或改用其他语言的可能性很高.

C++14 didn't deprecate rand(); it only deprecated functions in the C++ library that use rand(). While C++17 might deprecate rand(), it won't delete it. That means you have several more years before rand() disappears. The odds are high that you will have retired or switched to a different language by the time the C++ committee finally does delete rand() from the C++ standard library.

我正在创建随机输入,以使用类似于std::vector<int> v(size); std::generate(v.begin(), v.end(), std::rand);

您不需要为此使用加密安全的PRNG.您甚至都不需要Mersenne Twister.在这种情况下,rand()可能足以满足您的需求.

You don't need a cryptographically secure PRNG for that. You don't even need Mersenne Twister. In this particular case, rand() probably is good enough for your needs.


更新
在C ++ 11随机库中,可以很好地替换rand()srand():std::minstd_rand.


Update
There is a nice simple replacement for rand() and srand() in the C++11 random library: std::minstd_rand.

#include <random>
#include <iostream>

int main ()
{
    std:: minstd_rand simple_rand;

    // Use simple_rand.seed() instead of srand():
    simple_rand.seed(42);

    // Use simple_rand() instead of rand():
    for (int ii = 0; ii < 10; ++ii)
    {
        std::cout << simple_rand() << '\n';
    }
}

函数std::minstd_rand::operator()()返回std::uint_fast32_t.但是,该算法将结果限制在1到2 31 -2(含)之间.这意味着结果将始终安全地转换为std::int_fast32_t(如果int至少为32位长,则转换为int).

The function std::minstd_rand::operator()() returns a std::uint_fast32_t. However, the algorithm restricts the result to between 1 and 231-2, inclusive. This means the result will always convert safely to a std::int_fast32_t (or to an int if int is at least 32 bits long).

这篇关于如何使用&lt; random&gt;替换rand()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆