Understanding how recursive functions work

后端 未结 18 791
野性不改
野性不改 2020-11-22 07:08

As the title explains I have a very fundamental programming question which I have just not been able to grok yet. Filtering out all of the (extremely clever) \"In order to

相关标签:
18条回答
  • 2020-11-22 07:36

    Think recursion as a multiple clones doing same thing...

    You ask to clone[1]: "sum numbers between 2 and 5"

    + clone[1]               knows that: result is 2 + "sum numbers between 3 and 5". so he asks to clone[2] to return: "sum numbers between 3 and 5"
    |   + clone[2]           knows that: result is 3 + "sum numbers between 4 and 5". so he asks to clone[3] to return: "sum numbers between 4 and 5"
    |   |   + clone[3]       knows that: result is 4 + "sum numbers between 5 and 5". so he asks to clone[4] to return: "sum numbers between 5 and 5"
    |   |   |   + clone[4]   knows that: result is 5 + "sum numbers between 6 and 5". so he asks to clone[5] to return: "sum numbers between 6 and 5"
    |   |   |   |   clone[5] knows that: he can't sum, because 6 is larger than 5. so he returns 0 as result.
    |   |   |   + clone[4]   gets the result from clone[5] (=0)  and sums: 5 + 0,  returning 5
    |   |   + clone[3]       gets the result from clone[4] (=5)  and sums: 4 + 5,  returning 9
    |   + clone[2]           gets the result from clone[3] (=9)  and sums: 3 + 9,  returning 12
    + clone[1]               gets the result from clone[2] (=12) and sums: 2 + 12, returning 14
    

    and voilá!!

    0 讨论(0)
  • 2020-11-22 07:38

    I'll give it a go.

    Executing the equation a + sumInts(a+1, b), I will show how the final answer is 14.

    //the sumInts function definition
    func sumInts(a: Int, b: Int) -> Int {
        if (a > b) {
            return 0
        } else {
            return a + sumInts(a + 1, b)
        }
    }
    
    Given: a = 2 and b = 5
    
    1) 2 + sumInts(2+1, 5)
    
    2) sumInts(3, 5) = 12
       i) 3 + sumInts(3+1, 5)
       ii) 4 + sumInts(4+1, 5)
       iii) 5 + sumInts(5+1, 5)
       iv) return 0
       v) return 5 + 0
       vi) return 4 + 5
       vii) return 3 + 9
    
    3) 2 + 12 = 14.
    

    Let us know if you have any further questions.

    Here's another example of recursive functions in the following example.

    A man has just graduated college.

    t is the amount of time in years.

    The total actual number of years worked before retiring, can be calculated as follows:

    public class DoIReallyWantToKnow 
    {
        public int howLongDoIHaveToWork(int currentAge)
        {
          const int DESIRED_RETIREMENT_AGE = 65;
          double collectedMoney = 0.00; //remember, you just graduated college
          double neededMoneyToRetire = 1000000.00
    
          t = 0;
          return work(t+1);
        }
    
        public int work(int time)
        {
          collectedMoney = getCollectedMoney();
    
          if(currentAge >= DESIRED_RETIREMENT_AGE 
              && collectedMoney == neededMoneyToRetire
          {
            return time;
          }
    
          return work(time + 1);
        }
    }
    

    And that should be just enough to depress anyone, lol. ;-P

    0 讨论(0)
  • 2020-11-22 07:40

    Recursion started making sense to me when I stopped reading what others say about it or seeing it as something I can avoid and just wrote code. I found a problem with a solution and tried to duplicate the solution without looking. I only looked at the solution when I got helplessly stuck. Then I went back at trying to duplicate it. I did this again on multiple problems until I developed my own understanding and sense of how to identify a recursive problem and solve it. When I got to this level, I started making up problems and solving them. That helped me more. Sometimes, things can only be learned by trying it out on your own and struggling; until you “get it”.

    0 讨论(0)
  • 2020-11-22 07:42

    You've got some good answers here so far, but I'll add one more that takes a different tack.

    First off, I have written many articles on simple recursive algorithms that you might find interesting; see

    http://ericlippert.com/tag/recursion/

    http://blogs.msdn.com/b/ericlippert/archive/tags/recursion/

    Those are in newest-on-top order, so start from the bottom.

    Second, so far all of the answers have described recursive semantics by considering function activation. That each, each call makes a new activation, and the recursive call executes in the context of this activation. That is a good way to think of it, but there is another, equivalent way: smart text seach-and-replace.

    Let me rewrite your function into a slightly more compact form; don't think of this as being in any particular language.

    s = (a, b) => a > b ? 0 : a + s(a + 1, b)
    

    I hope that makes sense. If you're not familiar with the conditional operator, it is of the form condition ? consequence : alternative and its meaning will become clear.

    Now we wish to evaluate s(2,5) We do so by doing a textual replacing of the call with the function body, then replace a with 2 and b with 5:

    s(2, 5) 
    ---> 2 > 5 ? 0 : 2 + s(2 + 1, 5)
    

    Now evaluate the conditional. We textually replace 2 > 5 with false.

    ---> false ? 0 : 2 + s(2 + 1, 5)
    

    Now textually replace all false conditionals with the alternative and all true conditionals with the consequence. We have only false conditionals, so we textually replace that expression with the alternative:

    ---> 2 + s(2 + 1, 5)
    

    Now, to save me having to type all those + signs, textually replace constant arithmetic with its value. (This is a bit of a cheat, but I don't want to have to keep track of all the parentheses!)

    ---> 2 + s(3, 5)
    

    Now search-and-replace, this time with the body for the call, 3 for a and 5 for b. We'll put the replacement for the call in parentheses:

    ---> 2 + (3 > 5 ? 0 : 3 + s(3 + 1, 5))
    

    And now we just keep on doing those same textual substitution steps:

    ---> 2 + (false ? 0 : 3 + s(3 + 1, 5))  
    ---> 2 + (3 + s(3 + 1, 5))                
    ---> 2 + (3 + s(4, 5))                     
    ---> 2 + (3 + (4 > 5 ? 0 : 4 + s(4 + 1, 5)))
    ---> 2 + (3 + (false ? 0 : 4 + s(4 + 1, 5)))
    ---> 2 + (3 + (4 + s(4 + 1, 5)))
    ---> 2 + (3 + (4 + s(5, 5)))
    ---> 2 + (3 + (4 + (5 > 5 ? 0 : 5 + s(5 + 1, 5))))
    ---> 2 + (3 + (4 + (false ? 0 : 5 + s(5 + 1, 5))))
    ---> 2 + (3 + (4 + (5 + s(5 + 1, 5))))
    ---> 2 + (3 + (4 + (5 + s(6, 5))))
    ---> 2 + (3 + (4 + (5 + (6 > 5 ? 0 : s(6 + 1, 5)))))
    ---> 2 + (3 + (4 + (5 + (true ? 0 : s(6 + 1, 5)))))
    ---> 2 + (3 + (4 + (5 + 0)))
    ---> 2 + (3 + (4 + 5))
    ---> 2 + (3 + 9)
    ---> 2 + 12
    ---> 14
    

    All we did here was just straightforward textual substitution. Really I shouldn't have substituted "3" for "2+1" and so on until I had to, but pedagogically it would have gotten hard to read.

    Function activation is nothing more than replacing the function call with the body of the call, and replacing the formal parameters with their corresponding arguments. You have to be careful about introducing parentheses intelligently, but aside from that, it's just text replacement.

    Of course, most languages do not actually implement activation as text replacement, but logically that's what it is.

    So what then is an unbounded recursion? A recursion where the textual substitution doesn't stop! Notice how eventually we got to a step where there was no more s to replace, and we could then just apply the rules for arithmetic.

    0 讨论(0)
  • 2020-11-22 07:43

    Recursion. In Computer Science recursion is covered in depth under the topic of Finite Automata.

    In its simplest form it is a self reference. For example, saying that "my car is a car" is a recursive statement. The problem is that the statement is an infinite recursion in that it will never end. The definition in the statement of a "car" is that it is a "car" so it may be substituted. However, there is no end because in the case of substitution, it still becomes "my car is a car".

    This could be different if the statement were "my car is a bentley. my car is blue." In which case the substitution in the second situation for car could be "bentley" resulting in "my bentley is blue". These types of substitutions are mathematically explained in Computer Science through Context-Free Grammars.

    The actual substitution is a production rule. Given that the statement is represented by S and that car is a variable which can be a "bentley" this statement can be recursively reconstructed.

    S -> "my"S | " "S | CS | "is"S | "blue"S | ε
    C -> "bentley"
    

    This can be constructed in multiple ways, as each | means there is a choice. S can be replaced by any one of those choices, and S always starts empty. The ε means to terminate the production. Just as S can be replaced, so can other variables (there is only one and it is C which would represent "bentley").

    So starting with S being empty, and replacing it with the first choice "my"S S becomes

    "my"S
    

    S can still be substituted as it represents a variable. We could choose "my" again, or ε to end it, but lets continue making our original statement. We choose the space which means S is replaced with " "S

    "my "S
    

    Next lets choose C

    "my "CS
    

    And C only has one choice for replacement

    "my bentley"S
    

    And the space again for S

    "my bentley "S
    

    And so on "my bentley is"S, "my bentley is "S, "my bentley is blue"S, "my bentley is blue" (replacing S for ε ends the production) and we have recursively built our statement "my bentley is blue".

    Think of recursion as these productions and replacements. Each step in the process replaces its predecessor in order to produce the end result. In the exact example of the recursive sum from 2 to 5, you end up with the production

    S -> 2 + A
    A -> 3 + B
    B -> 4 + C
    C -> 5 + D
    D -> 0
    

    This becomes

    2 + A
    2 + 3 + B
    2 + 3 + 4 + C
    2 + 3 + 4 + 5 + D
    2 + 3 + 4 + 5 + 0
    14
    
    0 讨论(0)
  • 2020-11-22 07:43

    I was having hard time to understanding recursion then i found this blog and i already seen this question so i thought i must have to share . You must read this blog i found this extremely helpful it explain with stack and even it explain how two recursion works with stack step by step. I recommend you first understand how stack works which it explain very well here : journey-to-the-stack

    then now you will understand how recursion works now take a look of this post : Understand recursion step by step

    Its a program :

    def hello(x):
        if x==1:
            return "op"
        else:
            u=1
            e=12
            s=hello(x-1)
            e+=1
            print(s)
            print(x)
            u+=1
        return e
    
    hello(3)
    

    0 讨论(0)
提交回复
热议问题