请帮我理解这个递归函数

时间:2015-09-30 00:26:57

标签: javascript algorithm recursion

我正在尝试理解这种递归函数,并且更好地教育自己一般的递归。我似乎无法遵循这段代码是如何做到的。我希望有人能指引我完成这一切,这样我才能理解发生了什么。此函数获取数组的最大值,并检查数字的任何组合是否与此值相加。

function ArrayAdditionI(arr) {
  arr.sort(function(a,b){  //sort array;
    return a - b;
  });
  console.log('Sorted Array: ['+arr+']');
  var largest = arr.pop();  //grab last value aka largest

  function recursion(target, array){
    if(array.length === 0) {  //if array is empty return boolean
        return target === 0;
    }
    var n = array[0];       //first value of array
    array = array.slice(1);
    console.log('Array: [' +array+']');
    console.log('Target: '+target);
    return recursion(target,array) || recursion(target - n, array);   //not exactly sure about this ???
  }
  return recursion(largest,arr);  //call recursion function
}

console.log(ArrayAdditionI([4,6,21,10,20,1]));

以下是我通过调用此结果获得的结果。我已对他们发表评论,以显示我迷路的地方。

Sorted Array: [1,4,6,10,20,21] 
Array: [4,6,10,20]  //first value and largest value removed
Target: 21          //target highest value
Array: [6,10,20]    //first value removed again
Target: 21          //still 21
Array: [10,20]      //another value removed
Target: 21
Array: [20]         //last value in array
Target: 21
Array: []           //empty array.. Why did this not return a false???
Target: 21          
Array: []           //why is it doing this twice?
Target: 11          //where in the world did this come from. I see 21 - 10 but how did that happen?
Array: [20]         //When did this value get added back to the array?
Target: 15          //Totally lost at this point...
Array: []
Target: 15
Array: []
Target: 5
Array: [10,20]      //Where are these values coming from?
Target: 17
Array: [20]
Target: 17          //why does the target keep changing??
Array: []          
Target: 17
Array: []           
Target: 7
Array: [20]
Target: 11          //from 17 to 7 then back to 11?
Array: []
Target: 11
Array: []           //Empty arrays still not returning false??
Target: 1
Array: [6,10,20]    //No idea how these combinations are being generated.
Target: 20
Array: [10,20]
Target: 20
Array: [20]
Target: 20
Array: []
Target: 20
true                //Right answer but how?

2 个答案:

答案 0 :(得分:4)

我希望这能让你走上正轨:

  

数组:[] //空数组..为什么这不返回false ???

因为检查完成后数组不为空。 slice调用删除了最后一项时,它变空了。当数组为空时,后面的调用将返回false进入函数。

  

数组:[] //为什么这样做两次?

由于表达式recursion(target,array) || recursion(target - n, array)。每个都使用带有单个项目的数组调用,并在删除项目时显示空数组。

  

目标:11 //这个世界在哪里来自。我看到21    - 10但是这是怎么发生的?

这是recursion(target - n, array)target == 21时调用的n == 10

  

数组:[20] //这个值何时被添加回数组?

它没有被添加回来,它是一个不同的数组。递归已经达到极限,它又回到了先前的状态,尝试下一种可能性。

  

目标:15 //此时完全丢失......

这是recursion(target - n, array)target == 21时调用的n == 6

  

数组:[10,20] //这些值来自哪里?

这又是后退一步。每个递归级别都将状态存储在堆栈中,以便它可以备份到先前的状态。

  

目标:17 //为什么目标会不断变化?

因为代码在recursion(target - n, array)调用的路径中尝试了不同的组合。使用target的新值调用该函数。

  

数组:[] //空数组仍未返回false ??

是的,他们这样做。每个空数组都会结束一个可能的组合,并使代码备份并尝试下一个组合。

  

数组:[6,10,20] //不知道如何生成这些组合。

追溯到数组为[4,6,10,20]的状态并切断4

  

是的//正确答案但是如何?

进入所有可能的组合,然后再找到合适的组合。

答案 1 :(得分:1)

我不确定您是否可以将其视为答案,但请查看。 这是你自己的代码,没有黑客和更好的诊断:

var data = fileService.readFile(cordova.file.dataDirectory,filename);
console.log(data) //return undefined