2016-04-10 16 views
-1

256 öğeden oluşan bir blok boyutuna sahip bir sınıf üzerinde çalışma. Ve her seferinde bir şey kaydetmeden önce ekleme işlevim çağrılır; [0,255] aralığında tekdüze rastgele bir int oluşturmak istiyorum. Benim yapmak istediğim şey, bu fonksiyonun önceki değerleri takip etmek için bitmesidir, böylece fonksiyondan bir dahaki sefere tekdüze rastgele int dağılımı, o şeylerin zaten orada bulunup bulunmadığını kontrol etmek yerine, bu değerleri otomatik olarak atlayacaktır. . Her ardışık çağrı daha önce tekdüze rasgele int dağılımı ile seçildi değil başka rasgele değerini belirlemek neredeHer geçişte rastgele düzgün dağılımın azaltılması

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++; 
} 

belirtilen bir aralık benim durumumda arasında bir değer belirleme Can [0255] üretilebilir? Eğer öyleyse, bu nasıl yapılır?

DÜZENLEME aşağıda bazı yorumlar düşündükten sonra, onlar iyi bir noktaya getirmiştir. Benim durumumda gerçekten ihtiyaç duyulan şey, 0 - 255 arasında değişen bir dizi 256 benzersiz anahtar değeri ve bunların rastgele karıştırılması veya karıştırılması gerekiyor. Bunu nasıl başarmaya çalışacağım diye biraz düşüneceğim, ama varsa, bunun güzel bir örneğini almaya istekliyse, bu kabul edilebilir. İşe koyulmayı umursamıyorum, ama zaman zaman geçebileceğim bir noktaya geldiğimde ve üzerinde çok fazla zaman harcamaya başladığımda, sadece bu noktayı aşmak istiyorum. üzerinde.

+2

çizgisinde olduğunu Sadece shuffle' '0 ... 255 dizisi yapmak ve. –

+0

@ T.C. Yok hayır; 256 dizisinde imzasız bir char olarak depolanan önceden tanımlanmış değerlere sahip bir anahtar üreteci veya tablo var. 1 baytlık hex değeri örneğin 0x03d2, bir 16x16 ızgaraya yapılan bir referanstır. koordinat değerleri daha sonra imzasız char çiftleri hex değerleri '0x03' ve' 0xd2' dir ve bu saklı bir referans değeri olacaktır. Tabloya bakma zaten tanımlanmış ve çalışıyor. Current sınıfım bu tabloyu kullanacak. Bilginin sadece doğrusal olarak eklenmesini istemiyorum. Onların rastgele yerleştirilmesini istiyorum. –

+0

@ T.C. Ekleme biraz daha yavaş, ancak tek 256'sı olduğundan bir performans vuruşu değil. Fakat bakma ve alma oldukça hızlıdır. Öğeleri rastgele saklayacak bir zincirleme kabı oluşturuyorum. Bir güvenlik özelliği gibi bir şey. Önceden oluşturulmuş tablo olmadan, elemanların sırası hiçbir anlam ifade etmeyecektir. –

cevap

0

Dizileri karıştırmak için standart bir algoritmaya sahibiz; Buna shuffle deniyor. O halde 0 ... 255 dizisini yapın, karıştırın, sonra ortaya çıkan listeden dışarı çıkıncaya kadar bekleyin ve tekrarlayın. İsterseniz bir sınıf şablonuna şeyi sarın:

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; 
}; 

Kullanımı

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 
İlgili konular