-1

处理一个块大小为 256 个元素的类。每次在我存储任何东西之前调用我的 add 函数;我想在 [0,255] 范围内生成一个统一的随机整数。我想做的是在此函数完成之前跟踪使用的先前值,以便下次通过该函数时,统一随机 int 分布将自动跳过这些值,而不必检查那里是否已经包含某些内容.

template<class T>
class SomeClass {
     struct Node {
         unsigned idx;
         std::shared_ptr<T> pT;

         Node() : idx(-1), pT(nullptr) {}
         Node( unsigned idx_, std::shared_ptr<T>& pT_ ) : idx(idx_), pT(pT_) {}
    }; // Node

private:
     Node m_storage[256];
     static unsigned m_elementCount;
     std::set<unsigned> m_indexesUsed; 
public:
    SomeClass(){}
    ~SomeClass(){}

    void add( T& obj );
}; // SomeClass

template<class T>
unsigned SomeClass<T>::m_elementCount = 0;    

template<class T>
void SomeClass<T>::add( T& obj ) {

    if ( m_elementCount == 256 ) {
        return; // My Code Base Is Bigger - If This Is Full This Array gets pushed into a vector, 
        // and all values get reset to default and we start over.
    }
    Node n;

    // Generate Uniform Random In Distribution In The Range of [0,255]
    // Excluding the Values from m_listIndexesUsed.
    n.idx =  std::uniform_random_int_distribution from [0,255] excluding previous selected numbers
    n.pT = std::make_shared<T>( obj );
    m_storage[n.idx] = n;
    m_indexesUsed.insert( n.idx );
    m_elementCount++;
}

是否可以在我的情况 [0,255] 的指定范围内确定一个值,其中在每个连续调用中确定另一个以前没有使用均匀随机 int 分布选择的随机值?如果是这样,这将如何完成?

编辑

在考虑了下面的一些评论之后,他们提出了一个很好的观点。在我的情况下,真正需要的是一组 256 个唯一键值,范围从 0 到 255,它们需要随机打乱或打乱。我会考虑如何尝试实现这一点,但如果有人愿意得到一个很好的例子,那是可以接受的。我不介意投入工作,但有时当我到达一个我似乎无法超越的点并且我开始在这上面花费太多时间时,我只想超越那个点以便我可以移动上。

4

1 回答 1

0

我们有一个标准算法来打乱序列;它被称为,嗯,shuffle。因此,制作一个 0...255 的序列,将其洗牌,然后从结果列表中取出,直到用完它,然后重复。如果需要,将整个内容包装到类模板中:

template<size_t N>
struct index_generator {

    // seeding method for illustration purposes only
    // see http://www.pcg-random.org/posts/cpp-seeding-surprises.html
    index_generator() : rng(std::random_device()()) {
        std::iota(indices.begin(), indices.end(), size_t{});
        reset(); 
    }

    explicit operator bool() const { return current < N; }

    // use [] if you don't need the bounds checking
    size_t operator()() { return indices.at(current++); }

    void reset() {
        std::shuffle(indices.begin(), indices.end(), rng);
        current = 0;
    }
private:
    std::array<size_t, N> indices;
    size_t current;
    std::mt19937 rng;
};

用法是沿着

index_generator<256> gen; // static(?) data member

// ...
if ( !gen ) {
    // we've exhausted the 256 indices
    // do whatever you need to do
    gen.reset();
    return;
}

Node n;
n.idx =  gen();
// other stuff
于 2016-04-11T21:07:50.400 回答