[英]C++11 Random between int x, int y, excluding list<int>
I need a way to generate random integers between x,y, but once a random z is generated, I need the next iteration of x,y to exclude z (or better yet, a list of ints to exclude). 我需要一种在x,y之间生成随机整数的方法,但是一旦生成随机z,我需要x,y的下一次迭代来排除z(或者更好的是,要排除的整数列表)。 The return value has to honor the "std::uniform_int_distribution<>" condition.
返回值必须符合“std :: uniform_int_distribution <>”条件。 There is an obvious way to do this, but I was hoping for a fast version.
有一种明显的方法可以做到这一点,但我希望有一个快速版本。
int GenerateRandomBetweenExcluding(int min, int max, int exclude) // even better is a list<int> to exclude
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(min, max); // how to exclude "exclude" or list<int>?
int randNum = dis(gen);
return randNum;
}
Use a list with all numbers between min and max. 使用包含最小值和最大值之间所有数字的列表。 Choose randomly an element and delete it.
随机选择一个元素并将其删除。
#include <algorithm>
#include <vector>
#include <random>
class NoRepeat
{
public:
void Init(int,int);
int GetOne();
bool HasMore();
private:
std::vector<int> list;
};
void NoRepeat::Init(int min, int max) // min and max are inclusive
{
list.clear();
list.reserve(max-min+1);
for( int i=min; i<=max; ++i )
list.push_back(i);
std::random_shuffle( list.begin(), list.end() );
// might want to supply own random_func, default uses rand()
}
bool NoRepeat::HasMore()
{
return !list.empty();
}
int NoRepeat::GetOne()
{
int ret = list.back();
list.pop_back();
return ret;
}
There's a nice way to do this if your exclusion list is sorted in ascending order. 如果您的排除列表按升序排序,有一种很好的方法可以做到这一点。 You can achieve this sorting by using a
set<int>
instead of a list<int>
to track exclusions; 您可以使用
set<int>
而不是list<int>
来跟踪排除项来实现此排序; most set operations take log(n)
time and the container is guaranteed to be sorted at all times. 大多数设置操作需要
log(n)
时间,并且保证容器始终排序。
The algorithm is as follows: 算法如下:
set<int> exclude;
/* ... configure generator and exclusion set ... */
uniform_int_distribution<> dis(min, max-exclude.size());
int val = dis(gen);
/* skip over the exclusions */
for(int i : exclude) {
if(val >= i) val++;
else break;
}
return val;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.