【问题标题】:Javascript array addition - all combinationsJavascript 数组加法 - 所有组合
【发布时间】:2015-02-03 14:01:32
【问题描述】:

我正在解决 Coderbyte 的数组添加问题:

使用 JavaScript 语言,让函数 ArrayAdditionI(arr) 获取存储在 arr 中的数字数组,如果数组中的任何数字组合可以相加等于数组中的最大数字,则返回字符串 true,否则返回字符串 false。例如:如果arr 包含[4, 6, 23, 10, 1, 3],则输出应返回true,因为4 + 6 + 10 + 3 = 23。该数组不会为空,不会包含所有相同的元素,并且可能包含负数。

我想出了下面的解决方案,但由于某种原因,无法使递归工作。该代码正确识别了剩余(非最大)数组元素恰好加起来最大的数组,否则失败。有什么建议吗?

function ArrayAdditionI(arr) { 
  arr = arr.sort(function(a,b) {return b-a});
  match = false;
  largest = arr.shift(arr[0]); 

  function test(a){
    if(eval(a.join("+"))==largest){
      match = true;
      return match}
    else {
      for(i = 0; i < a.length; i++){
        newArr = a.slice();
        newArr.splice(i,1);
        return test(newArr);
      }
    }
  }

  test(arr);
  return match;


}

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    eval 是邪恶的。在几乎所有情况下,它都可以在没有eval 的情况下完成,而且它会更快并且可能更安全。你的

    eval(a.join("+"))
    

    可以写成

    a.reduce(function(a, b) { return a + b; })
    

    现在已经不碍事了:您的递归有效。你的 loop 没有。在循环的第一次循环中,您已经返回了结果,因此每次递归中循环的第二次、第三次等迭代永远不会发生。

    这是您的代码,稍作改动:

    function ArrayAdditionI(arr) { 
      arr.sort(function(a,b) {return b-a;});
      var largest = arr.shift(); 
    
      function test(a) {
        var sum = a.reduce(function(a, b) { return a + b; }, 0);
        if (sum == largest) {
          return true;
        } else {
          for (var i = 0; i < a.length; i++) {
            var newArr = a.slice();
            newArr.splice(i,1);
            if (test(newArr)) {
              return true;
            }
          }
          return false;
        }
      }
    
      return test(arr);
    }
    var result = ArrayAdditionI([4, 6, 23, 10, 1, 3]);
    document.getElementById('result').textContent = result;
    &lt;div id="result"&gt;&lt;/div&gt;

    【讨论】:

    • 感谢您的回复!这就像一个魅力。出于好奇,为什么'for'循环需要实例化'var i = 0'而不是'i = 0'?
    • for 没有。但是你想var i 在函数的某个地方(不管你把它放在哪里,但最易读和最明智的应该是函数的顶部;如果它只用作循环计数器,在循环本身通常是可以接受的)。如果你不这样做,那么i“泄漏”并引用一个全局变量;泄露的全局变量可能会产生意想不到的后果。
    【解决方案2】:

    您也可以通过分离这两个函数并在 for loop 内部检查 test 函数来做到这一点:

     function ArrayAdditionI(arr) { 
    	  arr.sort(function(a,b) {return b-a;});
    	  var largest = arr.shift(); 
    	  return test(arr,largest);
    	}
      function test(a,largest) {
    	    if (eval(a.join("+")) == largest) {
    	      return true;
    	    } else {
    	      for (var i = 0; i < a.length; i++) {
    	        var newArr = a.slice();
    	        newArr.splice(i,1);
    	        if (test(newArr,largest)) {//check if test returns true then only return from this method otherwise the last line will return false after whole execution
    	          return true;
    	        }
    	      }
    	      return false;
    	    }
    	  }
    	var ar=[4, 6, 23, 10, 1, 3];
    	var result = ArrayAdditionI(ar);
    	alert(result);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 2019-04-18
      • 2014-02-11
      • 1970-01-01
      • 1970-01-01
      • 2018-08-18
      • 2018-07-31
      相关资源
      最近更新 更多