将数字分成相等的部分,然后填充为数组

时间:2019-02-01 07:52:45

标签: javascript

给出数字numberninterval,我试图将它们划分为相等的间隔,并将它们预先填充为数组。

规则是,如果我们将这些相等的间隔相加,则需要将其相加为原始数字。


示例:

  

输入:

number = 8, n = 2, interval = 4
  

输出:

+---+---+---+---+
| 2 | 2 | 2 | 2 |
+---+---+---+---+

  

输入:

number = 56, n = 8, interval = 7
  

输出:

+---+---+---+---+---+---+---+
| 8 | 8 | 8 | 8 | 8 | 8 | 8 |
+---+---+---+---+---+---+---+

输入 数字= 9,数字= 2,间隔= 3

输出

+---+---+---+
| 4 | 4 | 1 |
+---+---+---+

问题是我正在创建的数组没有按照间隔值平均分配。

这是我正在尝试的代码,

var dividend = 9,
  divisor = 2,
  interval = 3;

var res = (function(number, n, interval) {
  values = [];

  while (number && n && interval) {
    if (number % 2 == 0)
      a = Math.floor(number / n);
    else
      a = Math.ceil(number / n);

    n--;
    number -= a;
    interval--;

    values.push(a);
  }
  return values;
})(dividend, divisor, interval);



console.log(res);

4 个答案:

答案 0 :(得分:2)

您似乎需要三个部分的解决方案,其中

  • 总和等于值和长度的乘积

    然后将值分配到结果数组的整个长度

  • 总和小于值和长度的乘积,

    然后计算较大的值left,然后将此值作为计数分配到该值上,其余的取另一个值right

  • 总和大于值和长度的乘积,

    此处将值作为最大值进行分配,并计算左侧的计数和right侧的较小值。

function getParts(sum, n, length) {
    var left, right;
    if (n * length === sum) return Array.from({ length }, _ => n);
    if (n * length < sum) {
        left = Math.floor(sum / n);
    } else {
        left = n;
        n = Math.floor(sum / left);
    }
    right = (sum - left * n) / (length - n);
    return Array.from({ length }, (_, i) => i < n ? left : right);
}

console.log(getParts(8, 2, 4).join(' '));  // 2 2 2 2
console.log(getParts(56, 8, 7).join(' ')); // 8 8 8 8 8 8 8
console.log(getParts(9, 2, 3).join(' '));  // 4 4 1
console.log(getParts(10, 2, 3).join(' ')); // 5 5 0
console.log(getParts(9, 4, 3).join(' '));  // 4 4 1
console.log(getParts(8, 5, 4).join(' '));  // 5 1 1 1

对于具有几乎相等的值的和的几乎相同的分布,您可以得到以下内容。

function getParts(sum, length) {
    var left = Math.ceil(sum / length),
        right = Math.floor(sum / length),
        first = (sum - right * length) / right;

    return Array.from({ length }, (_, i) => i < first ? left : right);
}

console.log(getParts(8, 5).join(' ')); // 2 2 2 1 1
console.log(getParts(8, 4).join(' ')); // 2 2 2 2
console.log(getParts(8, 3).join(' ')); // 3 2 2
console.log(getParts(9, 3).join(' ')); // 3 3 3

答案 1 :(得分:1)

STEPS:

  1. 使用Math.ceil(number / (n * interval))查找化合物(我不知道该怎么称呼),以知道将n乘以interval中最大数量的次数。
  2. max_n中计算n * compound,这是每个interval中的最高数字。
  3. 迭代interval的数量。
  4. 在每次迭代中,
    • 如果您max_n高于或等于当前number,则将max_n减去number,再按max_n
    • 否则,其余的(number

var res = (function(number, n, interval) {
  let values = [];
  let compound = Math.ceil(number / (n * interval))
  let max_n = n * compound
  while (interval--) {
    if (number >= max_n) {
      values.push(max_n)
      number -= max_n
    }
    else {
      values.push(number)
    }
  }
  return values;
});

console.log(res(8, 2, 4));
console.log(res(56, 8, 7));
console.log(res(9, 2, 3));

答案 2 :(得分:1)

根据我对您的问题的了解,在填充数组fill * (interval - 1) <= numberfill * interval >= number(其中fillnumber / n开始)之前,必须满足这两个条件。基于此,我制定了可以在下面找到的算法。

function populate(number, n, interval) {
  var fill = Math.floor(number / n);
  if (fill * interval < number) fill = Math.ceil(number / interval);
  else if (fill * (interval - 1) > number) fill = Math.ceil(number / (number % interval ? interval - 1 : interval));
  var array = new Array(interval);
  array.fill(fill);
  array[interval - 1] = number - ((interval - 1) * fill);
  return array;
}

如果需要IE支持,请将array.fill更改为如下所示的for循环: for(var index = 0; index < interval - 1; index++) array[index] = fill;

我也做了一个代码段,因此您可以测试多个值

function populate(number, n, interval) {
  var fill = Math.floor(number / n);
  if (fill * interval < number) fill = Math.ceil(number / interval);
  else if (fill * (interval - 1) > number) fill = Math.ceil(number / (number % interval ? interval - 1 : interval));
  var array = new Array(interval);
  array.fill(fill);
  array[interval - 1] = number - ((interval - 1) * fill);
  return array;
}

document.querySelector("#calc").addEventListener("click", function() {
  var number = document.querySelector("#number").value - 0,
    n = document.querySelector("#n").value - 0,
    interval = document.querySelector("#interval").value - 0;
  console.log(JSON.stringify(populate(number, n, interval)));
});
<label for="number">Number</label>
<input id="number" type="number" name="number" value="9" />
<label for="n">n</label>
<input id="n" type="number" name="n" value="2" />
<label for="interval">interval</label>
<input id="interval" type="number" name="interval" value="3" />
<input id="calc" type="submit" value="calculate" />

答案 3 :(得分:0)

@KunalMukherjee首先,您必须确定哪一条是真正的规则,但对于所有情况而言,只有一条规则。 您说n代表除数,因此在情况3中,您有9/2 = 4.5〜4,并且array(3)适合[4,4,1]。但是,在情况1、8 / 2 = 4以及array(4)适合[4、4、0、0]而不适合[2、2、2、2]的情况下,使用相同的规则。因此,n不能代表除数,否则情况1的结果是错误的。