ルームメイトが面接に行って、これを手に入れました:
ルール:
rand(); の使用が許可されています。
RAND_MAX = 32 767;
除算または剰余を使用しない。
TODO: 1 つの int パラメーターを取り、範囲 0 からパラメーターの int を返す関数を作成します。
頭が痛い、眠れない。どんな助けでも感謝します。ありがとう
ルームメイトが面接に行って、これを手に入れました:
ルール:
rand(); の使用が許可されています。
RAND_MAX = 32 767;
除算または剰余を使用しない。
TODO: 1 つの int パラメーターを取り、範囲 0 からパラメーターの int を返す関数を作成します。
頭が痛い、眠れない。どんな助けでも感謝します。ありがとう
私のパブリック ドメインrandlibでは、次のように、浮動小数点、除算、乗算を使用せず、ビットマスキングとリジェクション サンプリングのみで実行します。
int ojr_rand(ojr_generator *g, int limit) {
int v, m = limit - 1;
m |= m >> 1;
m |= m >> 2;
m |= m >> 4;
m |= m >> 8; // m is smallest ((power of 2) - 1) > limit
do {
v = m & NEXT16(g); // 16-bit random number
} while (v >= limit);
return v;
}
最悪の場合 (制限は 2 のべき乗 + 1)、これは生成された数値の 50% 近くを拒否する可能性がありますが、最も高速な RNG を使用した除算や浮動小数点演算よりも高速であり、一般的にははるかに高速です。また、浮動小数点演算や mod とは異なり、正確です。つまり、3 の制限を要求すると、値 0、1、および 2 が、ほぼ等しいだけでなく、正確に等しい確率で取得されます。
c++11 が許可されている場合、これを簡単にするランダム ヘッダーが提供されます。
#include <random>
#include <iostream>
int Roll(int Max)
{
if(Max>32767)
Max=32767;
std::random_device generator;
std::uniform_int_distribution<int> distribution(0,Max);
return distribution(generator);
}
int main()
{
std::cout << Roll(10) << std::endl
<< Roll(10) << std::endl
<< Roll(999999) << std::endl;
}
詳細: http://en.cppreference.com/w/cpp/numeric/random
これは、RAND_MAXが問題によって提供され、C標準によって提供されていないことを前提としています。もちろん、提供された定数を使用できます。詳細については、http://en.cppreference.com/w/cpp/numeric/random/RAND_MAX
do { r = random();} while (r >= max_rand);
最初は、分数を掛ければうまくいくと思っていましたが、それは数学的な観点からはごまかしと見なすことができます。
int getRand(int max)
{
int val = rand();
while (val > max)
{
val -= max + 1;
}
return val;
}
RAND_MAX % max
これは、値 <= を他のすべてよりも 1 回以上カウントすることによって明らかにわずかにずれますがrand() % max
、同じ問題があるため、このエラーは許容できると想定しています ( max
<<MAX_RAND
の値の場合、エラーは重要ではありません)。