0

min2 つのパラメーターを受け取りmax、2 つの整数の間で乱数を生成するJavaScript 関数を作成しようとしています。その部分は簡単です。

物事が荒くなるのは、次のような条件を作成する必要があることです

function generateNum (min, max) {
  var randNumber = Math.ceil(Math.random()*(max - min)+min);

  if (randNumber === max) {
    // store the result (probably in an array) and generate a new 
    // number with the same behavior as randNumber (e.g. it is also
    // stores it's total in the array and recursively "re-generates 
    // a new number until max is not hit)
  }
}

これを再帰的に処理して、現在までの最大ヒット数の合計を保存し、結合してから返すという考え方です。

例: スクリプトは 5/10 の最小/最大パラメーターを受け取りますgenerateNum(5,10){}。によって生成された値randNumberが 5、6、7、8、または 9 の場合、再帰はなく、関数はその値を返します。によって生成された値が である場合、randNumberその1010は配列に格納され、関数は再帰的に「再試行」します (つまり、10 回生成されると、その値は追加のオブジェクトとして配列に格納され、関数の再試行)。プロセスが停止したとき (無限になる可能性がありますが、再帰ごとに繰り返される放物線状に減少する確率があります)。最終的な数値 (5、6、7、8、9) が生成されたmax値の合計に追加され、結果が返されます。

非常に珍しい数学のシナリオです。それが意味をなさない場合、どうすれば明確にできるか教えてください。

4

5 に答える 5

3

その部分は簡単です。

あなたが思っているほど簡単ではありません...あなたが持っているアルゴリズムは壊れています。最小値が得られることはほとんどありません。代わりにメソッドを使用しMath.floorて、範囲に 1 を追加します。

var randNumber = Math.floor(Math.random() * (max - min + 1)) + min;

これを再帰的に行うのは簡単です。それ自体からメソッドを呼び出すだけです。

function generateNum (min, max) {
  var randNumber = Math.floor(Math.random()*(max - min + 1)) + min;
  if (randNumber == max) {
    randNumber += generateNum(min, max);
  }
  return randNumber;
}

これを再帰なしで解決することもできます。

function generateNum (min, max) {
  var randNumber = 0;
  do {
    var num = Math.floor(Math.random()*(max - min + 1)) + min;
    randNumber += num;
  } while (num == max);
  return randNumber;
}

どちらの場合も配列を使用する必要はありません。最終的に個別の値は必要なく、必要なのは値の合計だけです。

于 2012-06-05T19:43:38.520 に答える
2

this にタグを付けたので、再帰的なソリューションは本当に必要ないと思いますfor-loop。これは、最大数が選択された回数を返します。

function generateNum (min, max) {
    var diff = max - min;
    if(diff <= 0)
        return;

    for(var i = 0; diff == Math.floor(Math.random()*(diff + 1)); i++);

    return i;
}

出力例:

generateNum(1,2)  // 3
generateNum(1,2)  // 1
generateNum(1,2)  // 0
generateNum(5,10) // 0
generateNum(5,10) // 1
于 2012-06-05T19:36:33.077 に答える
1

再帰的な方法:

function generateNum (min, max) {
  var res = Math.floor(Math.random() * (max - min + 1)) + min;

  return (res === max) ? [res].concat(generateNum(min, max)) : res;
}
于 2012-06-05T19:36:59.563 に答える
1

2つのこと:

1) 10 滞在をロールする確率 (理論的には、各ロール (再試行) で同じ)、低い確率は、10 回連続で n 回ヒットすることです。

2) 再帰が必要な理由がわかりません。while ループはどうですか?

 var randNumber;
 var arr = [];
 while ((randNumber = Math.ceil(Math.random()*(max - min)+min)) === max) {
   arr.push(
 }
于 2012-06-05T19:38:50.487 に答える
1

再帰と配列だけでなく、for ループさえも使用する必要がないという考えを検討したいと思います。次のような単純な式が必要だと思います (わかりやすくするために 3 つに分けています)。

function generateNum (min, max)
{
    var randTail = Math.floor(Math.random()*(max - min)+min);
    var randRepeatMax = Math.floor(Math.log(Math.random()) / Math.log(1/(max-min+1)));
    return randRepeatMax*max + randTail;
}

ある乱数が別の乱数と同等であると仮定すると、これにより、単純なループと同じ値の分布が得られるはずです。

于 2012-06-05T20:22:12.760 に答える