1

これが私の最初の質問です。私は小さなゲームを作っています。役割を割り当てるには、乱数が必要です。私はこのコードを持っていますが、番号が繰り返されない可能性はありますか?ありがとう。

void giveroles() {
    srand(time(NULL));
    int r = rand() % i + 1; 
    switch ( r ) { /* ... */ }
}
4

3 に答える 3

4

少数の数値セットをランダムに生成するのではなく、ランダムに割り当てたい場合は、必要な数値のリストを作成してから、リストの順序をランダム化します (リストを繰り返し、エントリをランダムに入れ替えます)。

例えば:

int cards[52];
for(int i = 0 ; i < 52 ; i++)
{
    cards[i] = i;
}
for(int i = 0 ; i < 1000 ; i++)
{
    int r1 = rand()%52;
    int r2 = rand()%52;
    int t = cards[r1];
    cards[r1] = cards[r2];
    cards[r2] = t;
}
for(int i = 0 ; i < 52 ; i++)
{
    printf("%d\n", cards[i]);
}

完全を期すために、この方法でのシャッフルには偏りがあることが指摘されています。偏りのないバリエーションを次に示します。

cards[0] = 0;
for(int i = 1 ; i < 52 ; i++)
{
    int r = rand() % (i+1);
    cards[i] = cards[r];
    cards[r] = i;
}

(さらに、rand() の範囲が偶数倍にならないため、rand() のモジュールを取得することもバイアスがかかる可能性があることに注意してください)

于 2012-12-23T12:40:18.510 に答える
3

行を取り出しますsrand(time(NULL));。一般に、これはプログラム内で1回だけ実行する必要があります。たとえば、の開始時にmain()、への後続の呼び出しで使用されるシードをランダム化するためrand()です。

于 2012-12-23T12:26:33.547 に答える
3

乱数を繰り返したくない場合の解決策は、以前に使用した乱数を追跡することです。既存の数のリストに「ヒット」した場合は、もう一度試してください。

また、使用srand(time(NULL));は一度だけにしてください。これは、あなたが実際に求めていた質問であると思います。

于 2012-12-23T12:29:06.827 に答える