【问题标题】:Taking part from array of numbers by percent按百分比参与数字数组
【发布时间】:2018-03-12 21:33:14
【问题描述】:

让我们举个例子,数组中的数字大于 0:

let prices = [10,6200,20,20,350,900,26,78,888,10000,78,15000,200,1280,2000,450];

在我们将所有数字相加并得到总金额(例如,它是33770)之后,我们希望从这个总金额中提取一些 %(部分)。假设 5% (1689)。

我们的输出将是来自第一个数组的最佳候选数组。当然,该值不必正好是 5%,但它不能超过 5%,而且它必须包含尽可能大的数字。

我尝试了一些算法,但它无法预测并且非常不准确。

编辑:我想到了使用包含和排除原则。可以帮忙吗?

【问题讨论】:

  • 显示您尝试过的算法。询问为什么它无法预测。
  • 我们的输出将是来自第一个数组的最佳候选数组?这是什么意思?
  • 您期望实际值的结果如何?
  • @Ele 来自第一个数组女巫的数字数组将具有第一个数组的 10% 的值
  • 先对数组求和。然后计算总数和10%。然后,您将要对数组进行排序,从最小到最大,然后累积总数直到小于但不超过 10%,在您的示例 3377 中。

标签: javascript node.js algorithm sorting


【解决方案1】:

基本上,您可以将索引处的元素添加到临时数组中,也可以不添加。然后,检查索引是否达到数组长度总和是否大于所需总和。然后,要么检查总和并将临时数组添加到结果集中,要么不检查。最后,继续直到所有索引都被访问。

function getCombinations(array, sum) {
    function add(a, b) { return a + b; }

    function fork(i, t) {
        var r = (result[0] || []).reduce(add, 0),
            s = t.reduce(add, 0);
        if (i === array.length || s > sum) {
            if (s <= sum && t.length && r <= s) {
                if (r < s) {
                    result = [];
                }
                result.push(t);
            }
            return;
        }
        fork(i + 1, t.concat([array[i]]));
        fork(i + 1, t);
    }

    var result = [];
    fork(0, []);
    return result;
}

var result = getCombinations([10, 6200, 20, 20, 350, 900, 26, 78, 888, 10000, 78, 15000, 200], 1689)

console.log(result[0].reduce((a, b) => a + b));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 这很好。它对我来说没什么魔力,但有时我会理解它:D 谢谢,我认为这是正确的答案。只是可能添加到代码中,它将以项目数量最少的结果作为获胜者
【解决方案2】:

您可以使用函数reducesort 来获取最高值。

let prices = [10,6200,20,20,350,900,26,78,888,10000,78,15000,200],
    percentage = .05;
    total = prices.reduce((a, n) => a + n, 0),
    sorted = prices.sort((a, b) => b - a),
    {result} = sorted.reduce((a, n) => {
      if ((a.sum + n) <= (total * percentage)) {
        a.sum += n;
        a.result.push(n)
      }
      return a;
    }, {sum: 0, result: []});


console.log(`Lesser than ${(total * percentage)}: `, result.reduce((a, n) => a + n, 0) <= (total * percentage));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 他把它改成了 5%。你能修改你的答案吗?我想看它运行。
  • 重复值不是问题。更大的问题是我不想从最低到最高。我想让它变得更聪明,而不是仅仅取最低值并上升
  • 这家伙可能正在寻找一维装箱问题。
  • 实际上是背包问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
相关资源
最近更新 更多