-1

ブロック サイズが 256 要素のクラスに取り組んでいます。そして、何かを保存する前に add 関数が呼び出されるたびに。[0,255] の範囲で均一なランダムな int を生成したい。私がやりたいのは、この関数が終了する前に、使用された以前の値を追跡することです。これにより、次回関数を使用すると、何かが既にそこに含まれているかどうかを確認する代わりに、一様ランダム 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] の間の値を決定できますか? もしそうなら、これはどのように行われますか?

編集

以下のコメントのいくつかを検討した後、彼らは良い点をもたらしました. 私の場合、本当に必要なのは、0 ~ 255 の範囲の 256 個の一意のキー値のセットであり、ランダムにシャッフルまたはスクランブルする必要があります。これをどのように達成しようとするかについて考えてみますが、良い例を喜んで提供してくれる人がいれば、それは受け入れられます。仕事をすることは気にしませんが、乗り越えられないように見える点に到達し、それに時間を費やしすぎると、その点を超えて移動できるようになりたいと思うことがあります.の上。

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 に答える