【问题标题】:Need to Optimize the function需要优化功能
【发布时间】:2017-04-02 14:37:48
【问题描述】:

我正在处理这个函数,它必须返回添加 ab n 次的所有可能值,例如如果 n = 1 那么可能的值将是 a + a a + b 和 @987654327 @。下面的功能有效,但它太慢了,我想优化它。有什么建议?非常感谢!

function processData(n, a, b){
  var ans = [0];
  for(var i = 0; i < n; i++){
    var temp = [];
    for(var j = 0; j < ans.length; j++){
      var aa = ans[j] + a;
      if(temp.includes(aa) === false){
       temp.push(aa);
      }
      var bb = ans[j] + b;
      if(temp.includes(bb) === false){
        temp.push(bb);
      }
    }
    ans = temp;
  }
  ans.sort(function(a, b){return a - b});
  return ans;
}

【问题讨论】:

  • 你能举出n=0和n=2的例子吗?
  • 如果n=0那么没有什么可做的,如果n=2那么你在n===1之后得到了什么加上aba+a+aa+b+a,@ 987654336@、a+a+ba+b+bb+b+b。希望这是有道理的。
  • 因此您可以简化结果,因为您可以删除重复项。
  • 所以你有一个可以用递归解决的模式。 n=1 -> 2a + (a+b) + 2b,n=2 -> 3a + (2)(2a+b) + (2)(2b + a) + 3b。你能不能也给我n=3,手工很难?
  • 为什么n=2 你列出了a+b+aa+a+b,而不是b+a+a?我会认为所有这 3 个,或者只有一个,但是两个......?

标签: javascript algorithm


【解决方案1】:
function processData(n, a, b) {
  var ans = [];
  if (a == b) {
    for (var i=0; i<n+1; i++) {
      ans.push(a * n);
    }
    return ans;
  } else if (a > b) {
    var temp = a;
    a = b;
    b = temp;
  }
  var diff = b - a;
  for (var i=0; i<n+1; i++) {
      ans.push(a * n + diff * i);
  }
  return ans;
}

好的,这是迄今为止最有效的解决方案。我刚刚在fiddle 上测试过。

所有其他三个解决方案都大大优于您的解决方案。我的比@abc123 好,因为不需要排序,比@georg 好,因为不需要使用集合或排序。

【讨论】:

  • 这很聪明!
  • 很好的解决方案!一个小的改进是在循环之外计算 a*n,它可能会对 a & n 上的大值产生很大的影响,因为重新计算乘积会很昂贵
  • @Gaafar 这很好。事实上,我们可以通过将前一个元素和 diff 相加来获得数组中的下一个元素来完全避免乘法。
【解决方案2】:

这是一个获得 a 和 b 职位的提案。

function combine(left, right) {

    function carry() {
        return c.reduceRight(function (r, _, i, o) {
            return r && !(o[i] = (o[i] + 1) % left.length);
        }, 1);
    }

    var c = Array.apply(null, { length: right.length }).map(function () { return 0; }),
        result = [];

    do {
        result.push(c.reduce(function (r, a, i) {
            r[left[a]].push(right[i]);
            return r;
        }, left.reduce(function (r, a) {
            r[a] = [];
            return r;
        }, {})));
    } while (!carry());
    return result;
}

console.log(combine(['a', 'b'], [1, 2, 3]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

只是为了披露一下,答案是我的一个,给出了一个更详细的类似但不完全一样的问题:Find all combinations of two arrays

【讨论】:

    【解决方案3】:

    这是一个简洁的 ES6 函数:

    function processData(n, a, b) {
        let diff = Math.abs(b-a), sum = Math.min(a,b) * (n+1) - diff;
        return diff ? Array.from(Array(n+2), _ => sum += diff) : [sum]; 
    }
    
    console.log(processData(2, 3, 5));

    【讨论】:

    • 这似乎错过了 b+b+b = 15.. 我想你只需要Array.from(Array(n+2), 来应对开头和结尾的多重自我。
    • 你说得对,@Keith,我已经相应地更新了。谢谢!
    【解决方案4】:

    简化算法

    // a+a 2 a 0 b
    // a+b, b+a 1a 1b
    // b+b 0a 2b
    
    // a+a+a, 3a 0b
    // a+b+a, a+a+b 2a 1b
    // b+b+a, a+b+b 1a 2b
    // b+b+b 0a 3b
    
    // a+a+a+a 4a 0b
    // a+a+a+b, b+a+a+a, a+a+b+a, a+b+a+a 3a 1b
    // a+a+b+b, a+b+a+b, a+b+b+a, b+a+a+b, b+a+b+a, b+b+a+a 2a 2b
    // a+b+b+b, b+a+b+b, b+b+a+b, b+b+b+a 1a 3b
    // b+b+b+b 4b
    
    // a+a+a+a+a 5a 0b
    // a+a+a+a+b, a+a+a+b+a, a+a+b+a+a, a+b+a+a+a, b+a+a+a+a+a 4a 1b
    // a+a+a+b+b, a+a+b+a+b, a+a+b+b+a, a+b+a+a+b, a+b+a+b+a, a+b+b+a+a, b+a+a+a+b, b+a+a+b+a, b+a+b+a+a, b+b+a+a+a 3a 2b
    // a+a+b+b+b, a+b+a+b+b 2a 3b
    // a+b+b+b+b 1a 4b
    // b+b+b+b+b 0a 5b
    function processData(n, a, b){
      var ans = [];
      for(var i = 0; i < n + 1; i++){
        aa = a * (n-i);
        bb = b * (i);
        ans.push(aa + bb)
      }
      ans.sort(function(a, b){return a - b});
      return ans;
    }
    
    console.log(processData(3, 1, 2));

    【讨论】:

      【解决方案5】:

      希望这样更快

      function process(a,b,n){
      out=[];
      //get difference
      f=a-b;
      var last=b*n;
      for(i=0;i<n;i++){
      out.push(last);
      last+=f;
      }
      return out;
      }
      

      我不确定这是否正确,因为我只是用几个值进行了测试。我想你想要别的东西。

      【讨论】:

      • 没有缩进?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-07
      • 1970-01-01
      • 2015-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多