在不重复的范围内生成随机数
Posted
技术标签:
【中文标题】在不重复的范围内生成随机数【英文标题】:Generate random number in range without repetition 【发布时间】:2015-12-27 04:49:42 【问题描述】:我正在使用 C++ 在给定范围内生成 n 个统一数字,而不会重复。我想将它保存在数组(不是向量)中。我找到了一个代码,但它不允许在不重复的情况下生成数字。
std::random_device rd; // only used once to initialise (seed) engine
std::mt19937 rng(rd()); // random-number engine used (Mersenne-Twister in this case)
std::uniform_int_distribution<int> uni(0,10-1); // guaranteed unbiased
auto random_integer = uni(rng);
比如我会生成5个0-9范围内的随机数比如
1 0 3 8 6
这是我的代码
typedef unsigned int U32, *PU32;
U32 total_num = 5;
U32 *rndArray = new U32[total_num];
for (U32 i = 0; i < total_num; i++)
std::random_device rd // only used once to initialise (seed) engine
std::mt19937 rng(rd());
std::uniform_int_distribution<int> uni(0,10-1);
auto random_integer = uni(rng);
rndArray[i] = random_integer ;
第二种方式,我使用了下面的代码,它允许不重复。但在 g++ 中不支持(我在 ubuntu 中使用 g++)
#include <random>
#include <algorithm>
#include <iterator>
#include <iostream>
typedef unsigned int U32;
int main()
U32 total_num = 5;
U32 *rndArray = new U32[total_num];
std::random_device rd;
std::mt19937 g(rd());
std::vector<int> v = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9;
std::shuffle(v.begin(), v.end(), g);
for (int i=0;i<5;i++)
rndArray[i]=v[i];
std::cout<< rndArray[i] << " ";
std::cout << "\n";
【问题讨论】:
【参考方案1】:有几种方法可以做到这一点。
如果随机数已经在数组中,则生成另一个,直到找到一个以前没有见过的数字。这实现起来很快,但理论上存在运行时间非常长的缺点。
在数组中创建整个范围,然后对其进行打乱。获取k个数,获取加扰数组的前k个元素。
【讨论】:
【参考方案2】:使用 Fisher-Yates 洗牌算法洗牌一个向量/数组,其中填充了所需范围内的所有数字:https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
【讨论】:
如果您想要uint64_t
范围内的 100 万个数字怎么办?【参考方案3】:
实现您想要的最简单的方法是执行用户 Untitled123 建议的操作(见下文)。编译:g++ -std=c++11 file.cpp
#include <vector>
#include <algorithm>
using namespace std;
int randomize(const int &i) return rand() % i;
int main()
srand(unsigned(time(0)));
int n = 10;
vector<int> sample(n);
// generate numbers 0 .. n-1
iota(sample.begin(), sample.end(), 0);
// shuffle elements
random_shuffle(sample.begin(), sample.end(), randomize);
// grab the first five elements after shuffling
vector<int> chosen(sample.begin(), sample.begin() + 5);
// do stuff
return 0;
【讨论】:
以上是关于在不重复的范围内生成随机数的主要内容,如果未能解决你的问题,请参考以下文章