静的ストレージ期間変数は、コードの実行が開始される前に初期化され、コンパイル時に計算可能な式で初期化する必要があります。
つまり、実行時まで決定できない変数を使用して初期化しないということです。を削除するstatic
と、エラーは消えますが、呼び出すたびに乱数ジェネレーターを再シードすることになります。
最初の乱数を要求する前に ( C 標準ライブラリのように)乱数シードを一度srand()/rand()
初期化してから、乱数関数を使用してシーケンス内の値を循環させる必要があります。それは次のようなもので行うことができます:
int rand4 (int numLimit) {
static int randSeed, needsInit = 1;
if (needsInit) { // This bit only done once.
randSeed = time(0);
needsInit = 0;
}
randSeed = (randSeed * 32719 + 3) % 32749;
return (randSeed % numLimit) + 1;
}
の典型的な実装はsrand()/rand()
次のようになります。
// RAND_MAX assumed to be 32767.
static unsigned long int next = 1;
void srand(unsigned int seed) { next = seed; }
int rand(void) {
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
next
シードがビューから隠されるように、独自のソース ファイルで。rand()
これは、最初に を呼び出さずに呼び出すsrand()
と、 を呼び出した場合と同じであるという予想される動作に従いますsrand (1)
。
そして、1 から 52 までのすべての数字を生成するには特定の数の呼び出しが必要であるというコメントに基づいて、これを使用してランダム化されたカードのデッキを生成しているように思えます。その場合、乱数を生成して既に見たものを破棄するよりも良い方法があります。
そのソリューションは、残りのデッキのサイズがどんどん小さくなっていくにつれて急速に劣化します。O(1) 時間と空間の解の場合は、Fisher-Yates シャッフルを使用します。
基本的なアルゴリズムは、並べ替えられていないリストを使用し、最後の要素をランダムに選択された要素と単純に交換して、リストのサイズを 1 減らします。
dim n[N] // gives n[0] through n[N-1]
for each i in 0..N-1: // initialise them to their indexes
n[i] = i // (use i+1 for 1-10 instead of 0-9).
nsize = N // starting pool size
do N times:
i = rnd(nsize) // give a number between 0 and nsize-1
print n[i]
nsize = nsize - 1 // these two lines effectively remove the used number
n[i] = n[nsize]
それによって生成される数値は次のとおりです。
<------ n[] ------>
0 1 2 3 4 5 6 7 8 9 nsize rnd(nsize) output
------------------- ----- ---------- ------
0 1 2 3 4 5 6 7 8 9 10 4 4
0 1 2 3 9 5 6 7 8 9 7 7
0 1 2 3 9 5 6 8 8 2 2
0 1 8 3 9 5 6 7 6 6
0 1 8 3 9 5 6 0 0
5 1 8 3 9 5 2 8
5 1 9 3 4 1 1
5 3 9 3 0 5
9 3 2 1 3
9 1 0 9