How does this recursion work?

前端 未结 11 540
轮回少年
轮回少年 2020-11-30 11:03

This is an example from Eloquent Javascript:

By starting from the number 1 and repeatedly either adding 5 or multiplying by 3, an infinite amount of

相关标签:
11条回答
  • 2020-11-30 11:19

    If you get rid of the pretty printing stuff, the code is a little easier to read:

    function findSequence(goal) {
        function find(start) {
            if (start == goal) {
                return true;
            } else if (start > goal) {
                return false;
            } else {
                return find(start + 5) || find(start * 3);
            }
        }
    
        return find(1);
    }
    

    The outer function, findSequence, dynamically creates a new function called find where goal is taken from the scope of the parent function. You could re-write it like this for clarity:

    function findSequence(start, goal) {
        if (start == goal) {
            return true;
        } else if (start > goal) {
            return false;
        } else {
            return findSequence(start + 5, goal) || findSequence(start * 3, goal);
        }
    }
    

    Now, you can see a little more clearly what happens. The recursive step is in the final return statement, which tries both start + 5 and start * 3 at each step and picks the branch that eventually returns true.

    Follow the logic of findSequence(1, 23) by hand and you'll understand how it works.

    0 讨论(0)
  • 2020-11-30 11:28

    goal is your objective and it's set to 24

    goal == 24
    

    Now we have this internal function find() that checks to see if start is equal to 24; its not. It also checks to see if start is greater then 24 this is also not true,

    find(1 "1")
    1 == 24 //false
    1 > 24 //false
    

    So it hits the else statement where it calls find again, this is where the null value from the else if() comes in. If the return is null then it calls the || part until it eventually finds the correct answer.

    return find(6, "(1 + 5)")
           find(11, "((1 + 5) + 5)")
           find(16, "(((1 + 5) + 5) +5)")
           find(21, "((((1+5) + 5) + 5) +5)")
           //next one returns null!
           //tries * by 3 on 21, 16, and 11 all return null 
    

    so it switches to the ||

    return find(3, "(1 * 3)")
           find(8, "((1 * 3) +5)")
           //some calls down +5 path but that returns null
           find(24, "(((1 * 3) + 5) * 3)")
    

    Finally! We have a true return and we have logged the path we took in the history var.

    0 讨论(0)
  • 2020-11-30 11:30

    This function starts with 1 and then tries to either add 5 to it or multiply it by 3. If that is equal to the goal, the function terminates and prints out the expression found. If not, it calls itself recursively with the value at that level until a match is found or until the values become too high.

    Does that help?

    0 讨论(0)
  • 2020-11-30 11:31

    The function runs a rather simple brute force search with backtracking: at each invocation level it tries adding 5 to the number, and see if starting from the resultant number gets you to the goal. If it does, the result is returned; otherwise, the number is multiplied by 3, and the search for the goal continues from that new number. As the recursion goes along, the textual representation of the expression producing the number is passed to the next invocation levels.

    The search for 14 goes as follows:

    (1,  "1")
    (5,  "1+5")
    (10, "(1+5)+5")
    (15, "((1+5)+5)+5") <<= Fail
    (30, "((1+5)+5)*3") <<= Fail
    (15, "(1+5)*3") <<= Fail
    (3,  "1*3")
    (8,  "(1*3)+5")
    (13, "((1*3)+5)+5")
    (18, "(((1*3)+5)+5)+5") <<= Fail
    (39, "(((1*3)+5)+5)*3") <<= Fail
    (24,  "((1*3)+5)*3") <<= Fail
    (9, "(1*3)*3")
    (14, "((1*3)*3)+5) <<= Success!
    
    0 讨论(0)
  • 2020-11-30 11:33

    someone could write out a couple times how find is getting called.

    Here you go:

    find(1, "1") -> find(3, "(1 * 3)")
                 -> find(8, "((1 * 3) + 5)")
                 -> find(24, "(((1 * 3) + 5) * 3)")
    
    0 讨论(0)
提交回复
热议问题