0

我正在尝试创建一个接受 2 个参数minmax在两个整数之间生成随机数的 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 的 min / max 参数generateNum(5,10){}。如果由 生成的值randNumber是 5、6、7、8 或 9,那么将没有递归,函数将返回该值。如果由 is 生成的值randNumber10则该值10存储在一个数组中,并且该函数现在递归地“重试”(意味着生成了 10 次,然后该值作为附加对象存储在数组中,并且功能重试)。当过程停止时(可能是无限的,但每次递归重复的概率呈抛物线递减)。最终数字 (5, 6, 7, 8, 9) 将添加到生成max值的总数中并返回结果。

相当不寻常的数学场景,如果这没有意义,请告诉我如何澄清。

4

5 回答 5

3

那部分很容易。

没有你想的那么简单……你的算法坏了;它几乎永远不会给你最小值。改用该Math.floor方法,并在范围内添加一个:

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

两件事情:

1) 滚 10 次的概率保持不变(理论上每次滚都相同(重试)),低概率是连续击中 n 次 10

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 循环。我认为您需要一个像这样的简单表达式(为清楚起见,分为三个):

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 回答