【问题标题】:how to improve this algorithm for combinations?如何改进组合算法?
【发布时间】:2020-04-18 08:06:26
【问题描述】:

我有这个问题,我需要找一个具体数字的组合,并且数字的总和应该是另外一个具体的数量,我想你可以通过代码理解我。

function get4() {

    function iter(temp) {
        return function (v) {
            var t = temp.concat(v);
            if (t.length === 4) {
                if (t.reduce(add) === 10) {
                    result.push(t);
                }
                return;
            }
            values.forEach(iter(t));
        };
    }

    const
        add = (a, b) => a + b,
        values = [1, 2, 3, 4],
        result = [];

    values.forEach(iter([]));
    return result;
}

console.log(get4().map(a => a.join(' ')));

使用此代码,我可以找到一个 4 位数字,他的总和为 10,数字很少,但如果尝试使用更大的数字,函数会崩溃,我的意思是,浏览器不会执行它。

我的问题在于这些数据

长度 = 493

总和是 = 42990

值是 = [500,400,300,200,100,90,80,70,60,50,40,30,20,10,5]

如何改进此代码?如果您有其他语言的其他解决方案,它也会对我有所帮助。

【问题讨论】:

  • 以什么方式改进?速度?美学?
  • 哦,你的意思是 改进 就像 让它工作 - 抱歉,没有阅读你提到崩溃部分的整个问题跨度>
  • 好吧,我需要浏览器可以执行它,如果它更快,我会很高兴,
  • 您当前的代码是否出错?
  • 既然您标记了这个 JavaScript,我不会将其作为正式答案发布,但我会将其解决为 Constraint satisfaction problem,例如Constraint Logic Programming

标签: javascript algorithm statistics combinations


【解决方案1】:

你可以:

// comments removed for simplicity
function combinationSumRecursive(
  candidates,
  remainingSum,
  finalCombinations = [],
  currentCombination = [],
  startFrom = 0,
) {
  if (remainingSum < 0) {
    return finalCombinations;
  }

  if (remainingSum === 0) {
    finalCombinations.push(currentCombination.slice());

    return finalCombinations;
  }
  
  for (let candidateIndex = startFrom; candidateIndex < candidates.length; candidateIndex += 1) {
    const currentCandidate = candidates[candidateIndex];

    currentCombination.push(currentCandidate);

    combinationSumRecursive(
      candidates,
      remainingSum - currentCandidate,
      finalCombinations,
      currentCombination,
      candidateIndex,
    );

    currentCombination.pop();
  }

  return finalCombinations;
}

function removesDuplicatesAndNon4Length(arr) {
  return arr.map(x => [...new Set(x)]).filter(x => x.length === 4); 
}

const tempResp = combinationSumRecursive([1, 2, 3, 4], 10);
const resp = removesDuplicatesAndNon4Length(tempResp);

console.log(resp);

注意:这是针对此特定程序修改的Combination Sum Problem 版本。

【讨论】:

  • 这段代码看起来并没有优化。尤其是removesDuplicatesAndNon4Length()的部分。为什么要生成超过 4 个数字的总和?
  • 目前还不清楚resp / result 是否应该只包含一个变体(可能不是 - 原始result 包含多个变体),以及是否应该没有像 [1,2 ,3,4] & [4,3,2,1] & 等
猜你喜欢
  • 2016-01-07
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-25
  • 2014-02-06
相关资源
最近更新 更多