JavaScripts的递归OR如何工作?

时间:2016-07-06 23:56:09

标签: javascript arrays recursion

问题:数组中数字的任意组合是否与数组的最大数字相加?

有一个Coderbyte答案original source,我无法理解。我试图将这个功能可视化,但它对我来说没有意义。这是:

function ArrayAdditionI(arr) { 
  arr.sort(function(a,b){
    return a - b;
  });
  var largest = arr.pop();
  function recursion(target,array){
    if(array.length === 0){
      return target === 0; 
    }
    var n = array[0];
    array = array.slice(1);
    return recursion(target,array) || recursion(target - n, array);
  }
  return recursion(largest,arr);        
}

因此,给定:

[3,5,-1,8,12]

应输出:

"true"

我的解释是,return语句将调用||周围的每个函数,然后调用从这些函数生成的任何函数,直到数组的长度为0。但是如何检查最大数字的正确加数呢?

2 个答案:

答案 0 :(得分:1)

该行

  return recursion(target,array) || recursion(target - n, array);

首先使用目标和调用recursion(),并删除第一个元素的数组。如果返回true(因为target为零并且数组为空),则||的右侧将被调用。只有当第一次通话返回undefinedfalse时,才会进行右侧通话。

因此,整个过程首先要找到最大的值,并使用该列表的其余部分调用递归过程。重复地,递归例程会撬开第一个值,然后检查是否存在等于列表其余部分中的目标的总和,,如果其总和等于目标减去,在列表的其余部分中撬开第一个值。

有助于稍微重新排列函数,以便可以跟踪行为:

function ArrayAdditionI(arr) { 
  arr.sort(function(a,b){
    return a - b;
  });
  var largest = arr.pop();
  function recursion(target,array){
    if(array.length === 0){
      return target === 0; 
    }
    var n = array[0];
    array = array.slice(1);
    console.log("target: " + target + " n: " + n);
    var r1 = recursion(target,array), r2 = recursion(target - n, array);
    console.log("(" + target + ", " + n + ") left: " + r1 + " right: " + r2);
    return r1 || r2;
  }
  return recursion(largest,arr);        
}

如果你用样本数组调用它:

ArrayAdditionI([3,5,-1,8,12]);

你得到以下追踪:

target: 12 n: -1
target: 12 n: 3
target: 12 n: 5
target: 12 n: 8
(12, 8) left: false right: false
target: 7 n: 8
(7, 8) left: false right: false
(12, 5) left: false right: false
target: 9 n: 5
target: 9 n: 8
(9, 8) left: false right: false
target: 4 n: 8
(4, 8) left: false right: false
(9, 5) left: false right: false
(12, 3) left: false right: false
target: 13 n: 3
target: 13 n: 5
target: 13 n: 8
(13, 8) left: false right: false
target: 8 n: 8
(8, 8) left: false right: true
(13, 5) left: false right: true
target: 10 n: 5
target: 10 n: 8
(10, 8) left: false right: false
target: 5 n: 8
(5, 8) left: false right: false
(10, 5) left: false right: false
(13, 3) left: true right: false
(12, -1) left: false right: true

因此||的左侧代表了查看是否可以在没有的情况下找到其中一个值的总和的方法,并且右侧会考虑您是否假设其中一个值是其中一个成分,可以找到总和。从前几行开始,您会看到递归跳过前四个值,从最小到最大,直到最后一次调用的数组为空。目标值仍为12,因此无效。

然后尝试包含值5(当target12时),给出7的目标和仅8的列表其中{1}};这也不起作用。继续,只有当流程进入原始调用的右侧时,target12n-1,事情才会开始抬头。由于12 - -11313 - 58,而8 - 80,因此有一组值总计为目标

答案 1 :(得分:0)

这有助于理解||

true  || 1 // => true
false || 1 // => 1


function returnTrue() {
  return true;
}

function returnFalse() {
  return false
}

returnTrue()   || 1 // => true
returnFalse()  || 1 // => 1