如何将javascript中的数字n分成x部分,其中所有部分的总和等于数字?

时间:2017-08-12 17:08:32

标签: javascript arrays math

我有一个数字,我需要分成5个部分。但是,我希望每个部分都是一个随机数。但是当所有部件加在一起时,它们等于原始数字。我不确定如何使用JavaScript执行此操作。此外,我不希望分割部分的min为0或1,我想自己设置min。

例如,数字是450.我希望分割的部分不小于60.所以首先,数组将是[60,60,60,60,60]。但是我想随机化,以便它们总计达到450.这样做最好的方法是什么?

谢谢!

这是我到目前为止所尝试的:

let i = 0;
let number = 450;
let numArray = [];
while(i <= 5){
  while(number > 0) {
    let randomNum = Math.round(Math.random() * number) + 1;
    numArray.push(randomNum);
    number -= randomNum;
  }
  i += 1;
}

6 个答案:

答案 0 :(得分:3)

将五个最小值(例如min = 60)加起来:

var minSum = 5 * min

然后获得原始号码(orNumber = 450)和minSum之间的差异。

var delta = orNumber - minSum

现在您可以获得4个不同的随机数,范围从0到独占1.

将这些数字按升序排序。

这些randoms的主要做法如下:

  • 从最后一个(或第一个为零)
  • 中减去它
  • 将此数字乘以delta并获得其中一个部分。

最后一部分是delta减去所有其他部分。

之后您只需将min添加到所有部分。

答案 1 :(得分:2)

让你的数字为N,让p n 为第n部分。获得5个部分:

  • p 1 = 0到N之间的随机数
  • p 2 = 0到N之间的随机数 - 1
  • p 3 = 0和N之间的随机数 - 2 - p 1
  • p 4 = 0和N之间的随机数 - p 3 - p 2 - p 1 < / LI>
  • p 5 = N - p 4 - p 3 - p 2 - p 1

修改

为了让它看起来更随机,在生成数字后随机播放

答案 2 :(得分:2)

此函数生成从0到1的随机数,将它们相加,以确定需要乘以它们以提供正确的范围。它的好处是所有数字都是公平分配的。

&#13;
&#13;
function divvy(number, parts, min) {

  var randombit = number - min * parts;
  var out = [];
  
  for (var i=0; i < parts; i++) {
    out.push(Math.random());
  }
  
  var mult = randombit / out.reduce(function (a,b) {return a+b;});
  
  return out.map(function (el) { return el * mult + min; });
}
var d = divvy(450, 6, 60)
console.log(d);
console.log("sum - " + d.reduce(function(a,b){return a+b}));
&#13;
&#13;
&#13;

答案 3 :(得分:1)

您可以使用do..while循环从原始数字中减去最小数字,在循环结束时保留原始数字的副本以将剩余部分推送到数组

&#13;
&#13;
let [n, total, m = n] = [450, 0];
const [min, arr] = [60, []];
do {
  n -= min; // subtract `min` from `n`
  arr.push(n > min ? min : m - total); // push `min` or remainder 
  total += arr[arr.length - 1]; // keep track of total
} while (n > min);

console.log(arr);
&#13;
&#13;
&#13;

要在结果数组中随机化输出,请选择大于min且小于n的数字,以在特定范围内创建随机数

&#13;
&#13;
let [n, total, m = n] = [450, 0];
const [min, arr, range = min + min / 2] = [60, []];

do {
  let r = Math.random() * (range - min) + min; // random number in our range
  n -= r; // subtract `min` from `n`
  arr.push(n > min ? r : m - total); // push `r` or remainder 
  total += arr[arr.length - 1]; // keep track of total
} while (n > min);

console.log(arr);
&#13;
&#13;
&#13;

答案 4 :(得分:0)

我为初学者制作了更长版本。

const n          = 450;
const iterations = 5;
const parts      = [];

// we'll use this to store what's left on each iteration
let remainder = n;

for (let i = 1; i <= iterations; i += 1) {
    // if it's the last iteration, we should just use whatever
    // is left after removing all the other random numbers
    // from our 450
    if (i === iterations) {
        parts.push(remainder);

        break;
    }

    // every time we loop, a random number is created.
    // on the first iteration, the remainder is still 450
    const part = Math.round(Math.random() * remainder);

    parts.push(part);

    // we must store how much is left after our random numbers
    // are deducted from our 450. we will use the lower number
    // to calculate the next random number
    remainder -= part;
}

// let's print out the array and the proof it still adds up
const total = totalFromParts(parts);

console.log(parts);
console.log('Total is still ' + total);

// this function loops through each array item, and adds it to the last
// just here to test the result
function totalFromParts(parts) {
    return parts.reduce((sum, value) => sum + value, 0);
}

答案 5 :(得分:0)

有更有效的方法对此进行编码,但为了解释解决问题的逻辑,这将逐步介绍,转换价值并解释逻辑。

// Set start number, number of fragments
// minimum fragment size, define fragments array

var n = 450
var x = 5
var minNumber = 60
var fragment = n / x

// stuff array with equal sized fragment values
var fragments = []
for (i = 0; i < x; i++) {
  fragments[i] = fragment;
}

document.write("fragments: " + fragments);

var delta = [];

// iterate through fragments array
// get a random number each time between the fragment size
// and the minimum fragment sized defined above
// for even array slots, subtract the value from the fragment
// for odd array slots, add the value to the fragment
// skip the first [0] value
for (i = 1; i< x; i++) {
  delta[i] = Math.floor(Math.random() * (fragment - minNumber));
  document.write("<br />delta: " + delta[i]);
  if((i % 2) == 1) {
    fragments[i] -= delta[i]
  }
  else {
    fragments[i] += delta[i]
  }
}

// set the initial fragment value to 0
fragments[0] = 0

// defines a function we can use to total the array values
function getSum(total, num) {
    return total + num;
}

// get the total of the array values, remembering the first is 0
var partialTotal = fragments.reduce(getSum)
document.write("<br />partial sum: " + partialTotal);

// set the first array value to the difference between
// the total of all the other array values and the original
// number the array was to sum up to
fragments[0] = (n - partialTotal)

// write the values out and profit.
document.write("<br />fragments: " + fragments);
var grandTotal = fragments.reduce(getSum)
document.write("<br />Grand total: " + grandTotal);

https://plnkr.co/edit/oToZe7LGpQS4dIVgYHPi?p=preview