简体   繁体   English

C ++ 11 int x,int y之间的随机数,不包括列表<int>

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM