2016-04-01 17 views
0

クラス 'NumSet'から別のオブジェクトを作成しようとしています。 NumSet Player1、player2; 1つの配列を乱数で適切に生成します。 しかし、2つ目のコピーはまったく同じです。 プレーヤー1の配列は、プレーヤー2の配列と同じです。 これを解決するには?おかげさまで (乱数で初期化)良好である{3,4,5,2,5} :C++でC'torを使用して2つの異なるランダムな配列を生成する方法は?

NumSet::NumSet() 
{ 
    srand(time(0)); 
    for (int i = 0; i < C_NUM; i++) {//Generate 2 random arrays. 
     n_cards[i] = (rand() % 10) + 1; 
    } 
} 

例えばplayer1の意志がそのように見えます。 私が解決する方法を知ってはいけない問題は、player2がまったく同じになります: {3,4,5,2,5}

+1

を呼び出すあなたは –

答えて

0

古いスタイルrandを使用する必要があり、その後、クラスの外srandを呼び出す汚れのいくつかのより多くを行うにはしたくない場合。 、クラスでstatic変数を持ってIsRandomSeededそれを呼び出すと、条件付きでsrand

bool NumSet::IsRandomSeeded=false; 

NumSet::NumSet() 
{ 
    if(!IsRandomSeeded) 
    { 
     srand(time(0)); 
     IsRandomSeeded = true; 
    } 

    for (int i = 0; i < C_NUM; i++) {//Generate 2 random arrays. 
     n_cards[i] = (rand() % 10) + 1; 
    } 
} 
+0

働いてくれてありがとう!静的変数がどのように役立つかを詳しく説明できますか? –

+0

C++の本をつかむ! – Ajay

3

rand()数ジェネレータではないが本当にランダム、それが生成する擬似ランダム与えられた1つの初期シードに基づく配列。同じ種を使って、何度も同じシーケンスを作ります。

time(NULL)から同じ種を得るのに十分な速さ(同じ秒内)で両方のオブジェクトを作成すると、まったく同じシーケンスになります。ソリューションは、乱数ジェネレータの初期化をクラスコンストラクタの外に移動することです(理想的にはmain()関数内)。あなたは実験 C++の機能を使用することを心配していない場合は

あなたもこれを使用することがあります。

std::experimental::reseed(); 
for (int i = 0; i < C_NUM; i++) { 
    n_cards[i] = std::experimental::randint(1, 10); 
} 

rand()ことはスレッドセーフではありません、それはあなたのケースで問題になることがあります。 srand()をコンストラクタ(!!!)の外側に移動できず、std::experimentalのものを使用することができない場合は、srand()を1回呼び出すフラグを持つ乱数を生成する静的関数を提供する必要があります。

static unsigned seed = time(NULL); 
srand(seed++); 

注:rand()が良い乱数発生器ではありません、それは均一な分布を生成しません、その利点は、高速かつカジュアルタスクのためになることです(代わりに直接time(NULL)が、増分番号を使用していませんこのように十分です)。

+0

は、私がc'torで何とかこの問題を解決することができます(一度にsrandを呼び出す)だけ、一度乱数ジェネレータをシードする必要がありますか?ミッションの必要条件の1つです。 –

+2

@IsanRivkinコンストラクタで配列を設定しても問題ありません。 'srand'を動かすだけです。 – jrok

1

利用可能であれば、C++ 11で提供されるランダムライブラリを使用してください。ここには簡単な例http://en.cppreference.com/w/cpp/numeric/randomがあります。

#include <iostream> 
#include <iomanip> 
#include <string> 
#include <map> 
#include <random> 
#include <cmath> 

int main() 
{ 
    // Seed with a real random value, if available 
    std::random_device r; 

    // Choose a random mean between 1 and 6 
    std::default_random_engine e1(r()); 
    std::uniform_int_distribution<int> uniform_dist(1, 6); 
    int mean = uniform_dist(e1); 
    std::cout << "Randomly-chosen mean: " << mean << '\n'; 

    // Generate a normal distribution around that mean 
    std::seed_seq seed2{r(), r(), r(), r(), r(), r(), r(), r()}; 
    std::mt19937 e2(seed2); 
    std::normal_distribution<> normal_dist(mean, 2); 

    std::map<int, int> hist; 
    for (int n = 0; n < 10000; ++n) { 
     ++hist[std::round(normal_dist(e2))]; 
    } 
    std::cout << "Normal distribution around " << mean << ":\n"; 
    for (auto p : hist) { 
     std::cout << std::fixed << std::setprecision(1) << std::setw(2) 
        << p.first << ' ' << std::string(p.second/200, '*') << '\n'; 
    } 
} 
関連する問題