2012-08-29 38 views
2

是否有函数在指定范围内生成k个随机数字? 例如,我想要0到100之间的5个随机数,有或没有替换。C++中的随机函数

+1

没有内置函数,但它是一个相当简单的函数。看看动态创建一个数组和rand函数。编辑:我站在第一个答案纠正看。 – sean

+0

你的意思是这样的http://www.cplusplus.com/reference/clibrary/cstdlib/rand/? –

+0

@drescherjm - 你可以称它5次。它会每次产生一个新的随机数。如果您不明白代码无法正常工作的原因,则需要给我们更多的帮助。 –

回答

3

例如,有Boost库,您可以使用它来生成随机数。 下面的代码生成从[0,100] 5个随机数字与更换

#include <vector> 
#include <boost/random/mersenne_twister.hpp> 
#include <boost/random/uniform_int_distribution.hpp> 

const int numWantedNumbers = 5; 

int main() 
{ 
    boost::random::mt19937 generator; 
    boost::random::uniform_int_distribution<> distribution(0, 100); 
    std::vector<int> result; 
    for (int i = 0; i < numWantedNumbers; ++i) 
     result.push_back(distribution(generator)); 
} 

如果你想生成的数字无需更换,只需检查它们是否 仍然可用:

#include <algorithm> 
#include <vector> 
#include <boost/random/mersenne_twister.hpp> 
#include <boost/random/uniform_int_distribution.hpp> 

const int numWantedNumbers = 5; 

int main() 
{ 
    boost::random::mt19937 generator; 
    boost::random::uniform_int_distribution<> distribution(0, 100); 
    std::vector<int> result; 
    while (result.size() < numWantedNumbers) 
    { 
     int number = distribution(generator); 
     if (std::find(result.begin(), result.end(), number) == result.end()) 
      result.push_back(number); 
    } 
} 

注意:在没有替换的例子中的拒绝采样有一个明显的缺点,即较长的向量很难创建。试试从100个数字中抽出99个出现 ,看看我的意思(甚至更好地从10000中抽取9999)。如果这 是一个问题,我建议创造一切可能的数字 的随机排列,然后切向量在所要求的大小:由juanchopanza

#include <algorithm> 
#include <vector> 
#include <boost/random/mersenne_twister.hpp> 
#include <boost/random/uniform_int_distribution.hpp> 

const int numWantedNumbers = 5; 

int main() 
{ 
    boost::random::mt19937 generator; 
    boost::random::uniform_int_distribution<> distribution(0, 100); 

    // Generate a vector with all possible numbers and shuffle it. 
    std::vector<int> result; 
    for (int i = 0; i <= 100; ++i) 
     result.push_back(i); 
    for (int i = 0; i <= 100; ++i) 
    { 
     int x = distribution(generator); 
     std::swap(result[i], result[x]); 
    } 

    // Truncate to the requested size. 
    result.resize(numWantedNumbers); 
} 

编辑根据建议:

在C++ 11的方式,最后一个变种是这样

#include <algorithm> 
#include <random> 
#include <vector> 

const int numWantedNumbers = 5; 

int main() 
{ 
    std::random_device device; 
    std::mt19937 generator(device()); 
    std::uniform_int_distribution<> distribution(0, 100); 

    // Generate a vector with all possible numbers and shuffle it. 
    std::vector<int> result; 
    for (int i = 0; i <= 100; ++i) 
     result.push_back(i); 
    std::random_shuffle(result.begin(), result.end()); 

    // Truncate to the requested size. 
    result.resize(numWantedNumbers); 
} 

g++-4.6编译它令人高兴的是,如果添加-std=c++0x开关。 (Tank to James Kanze)。

+0

如果需要的数字数量接近该范围,那么第二个算法可能非常慢。 (有时候)更好的解决方案是用可能的值填充一个'std :: vector',在其上调用'std :: random_shuffle',然后取第一个'n'。如果所需数字的数量远小于范围,此解决方案可能需要大量额外的内存。 –

+0

您可能想要补充的是,大部分内容也可以在C++ 11中使用,请参见[此处](http://en.cppreference.com/w/cpp/numeric/random)。 – juanchopanza

+0

@JamesKanze:我添加了一个不使用拒绝采样的变体。 – Mehrwolf