2016-04-10 10 views
-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]が生成され、指定された範囲私のケースの間の値を決定することはできますか?もしそうなら、これはどのように行われますか?

EDIT

以下のコメントのいくつかを検討した後、彼らは良い点を育ててきました。私の場合、本当に必要なのは0から255までの256の一意キー値のセットであり、ランダムにシャッフルまたはスクランブルする必要があります。私はそれを達成しようとする方法としていくつかの考えを与えますが、誰かが良い例を得ることを望むなら、それは受け入れられます。私は仕事をするのが大好きではありませんが、過去を過ごすことができず、あまりにも多くの時間を費やし始めたときに、その点を過ぎて行きたいと思います。に。

+2

のラインに沿っているだけで、それをshuffle' '0 ... 255の配列を作ると。 –

+0

@ T.C。いいえ。私は256の配列のunsigned charとして格納されている事前定義された値を持つキージェネレータまたはテーブルを持っています。たとえば0x03d2の1バイトの16進値は16x16グリッドへのルックアップ参照です。 coordの値であれば、符号なしのcharのペアhex値は '0x03'と' 0xd2'であり、これは格納された参照値になります。私のルックアップテーブルクラスはすでに定義され、動作しています。 My Currentクラスはこのルックアップテーブルを使用します。私は、情報がちょうど直線的に追加されることを望んでいません。私はそれらをランダムに配置したい。 –

+0

@ T.C。挿入はやや遅くなりますが、わずか256であるため、パフォーマンスが低下しません。しかし、検索と検索は非常に高速です。私は要素をランダムに格納する連鎖コンテナを作成しています。これはセキュリティ機能のようなものです。あらかじめ生成されたテーブルがなければ、要素の順序は意味をなさないでしょう。 –

答えて

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 
関連する問題