简体   繁体   English

请帮我理解这个递归函数

[英]Please help me understand this recursion function

I'm trying to understand this recursion function and better educate myself on recursion in general. 我试图理解这个递归函数,并且更好地教育自己一般的递归。 I can't seem to follow how this code does it's thing. 我似乎无法遵循这段代码是如何做到的。 I'm hoping someone can walk me through this so I can understand what's going on. 我希望有人能指引我完成这一切,这样我才能理解发生了什么。 This function takes the largest value of an array and checks to see if any combination of numbers add up to this value. 此函数获取数组的最大值,并检查数字的任何组合是否与此值相加。

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]));

Here are the results I get from calling this. 以下是我从调用此结果得到的结果。 I've commented on them to show where I get lost. 我已对他们发表评论,以显示我迷路的地方。

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?

I hope this gets you on the right track: 我希望这能让你走上正轨:

Array: [] //empty array.. Why did this not return a false??? 数组:[] //空数组..为什么这不返回假?

Because the array wasn't empty when the check was done. 因为检查完成后数组不为空。 It became empty when the slice call removed the last item. slice调用删除最后一项时变为空。 The calls that follow will return false when array is empty going into the function. 当数组为空时,后面的调用将返回false进入函数。

Array: [] //why is it doing this twice? 数组:[] //为什么这样做两次?

Because of the expression recursion(target,array) || recursion(target - n, array) 由于表达式recursion(target,array) || recursion(target - n, array) recursion(target,array) || recursion(target - n, array) . recursion(target,array) || recursion(target - n, array) Each of them are called with an array with a single item, and will show an empty array when they remove the item. 每个都使用带有单个项目的数组调用,并在删除项目时显示空数组。

Target: 11 //where in the world did this come from. 目标:11 //这个世界在哪里来自。 I see 21 - 10 but how did that happen? 我看到21 - 10但是这是怎么发生的?

That's the recursion(target - n, array) being called when target == 21 and n == 10 . 这是在target == 21n == 10时调用的recursion(target - n, array)

Array: [20] //When did this value get added back to the array? 数组:[20] //这个值何时被添加回数组?

It's not added back, it's a different array. 它没有添加回来,它是一个不同的阵列。 The recursion has reached its limit and it taking a step back to a previous state to try the next possibility. 递归已达到极限,它向后退一步,尝试下一个可能性。

Target: 15 //Totally lost at this point... 目标:15 //此时完全丢失了......

That's the recursion(target - n, array) being called when target == 21 and n == 6 . 这是在target == 21n == 6时调用的recursion(target - n, array)

Array: [10,20] //Where are these values coming from? 数组:[10,20] //这些值来自哪里?

That's another step back. 那是又一步了。 Each recursion level stores the state on the stack, so that it can back up to the previous state. 每个递归级别将状态存储在堆栈上,以便它可以备份到先前的状态。

Target: 17 //why does the target keep changing?? 目标:17 //为什么目标会不断变化?

Because the code is trying different combinations into the path of the recursion(target - n, array) call. 因为代码尝试将不同的组合放入recursion(target - n, array)调用的路径中。 The function is called with a new value for target . 使用target的新值调用该函数。

Array: [] //Empty arrays still not returning false?? 数组:[] //空数组仍然没有返回false?

Yes, they do. 是的,他们这样做。 Each empty array ends one possible combination, and makes the code back up and try the next combination. 每个空数组结束一个可能的组合,并使代码备份并尝试下一个组合。

Array: [6,10,20] //No idea how these combinations are being generated. 数组:[6,10,20] //不知道如何生成这些组合。

By tracking back to the state where the array was [4,6,10,20] and slicing off the 4 . 通过追溯到数组为[4,6,10,20]并切掉4

true //Right answer but how? 是的//正确的答案,但如何?

By going into every possible combination and out again until the right one was found. 通过进入每个可能的组合再次出来,直到找到正确的组合。

I'm not sure if you can consider it as an answer, but check it out. 我不确定你是否可以将其视为答案,但请查看。 This is your own code without hacks and with better diagnostics: 这是您自己的代码,没有黑客和更好的诊断:

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, level) {
        level++;
        console.log("Level: "+level);
        console.log("Entering: " + target + " [" + array + "]");
        if (array.length === 0) { //if array is empty return boolean
            console.log("Array empy, is target 0? " + (target === 0));
            result = (target === 0);
        } else {
            var n = array[0]; //first value of array
            array = array.slice(1);
            console.log('Calling return: target=' + target + ', n=' + n + ', ' + '[' + array + ']');
            var result = recursion(target, array, level);
            if (result === true){ 
                console.log("Path 1: true");
            } else {
                result = recursion(target - n, array, level);
                console.log("Path 2: "+result);
            }
        }
        console.log('Returning level='+level+': '+result);
        console.log(); //spacer
        level--;
        return result;
    }
    return recursion(largest, arr, 0); //call recursion function
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM