Recursion - see Recursion
Recursion We know that: But…can a method call itself…? We can define classes We can define methods on classes Mehtods can call other methods But…can a method call itself…? DCS – SWC
Recursion public void callMe() { System.out.println(”Hello”); } DCS – SWC
Recursion Previous method definition was legal, but hardly useful… Just calling the same method will result in an infinite loop BUT what if we Supply a parameter to the method Change the parameter in each call Stop calling ourselves for some specific value DCS – SWC
Recursion public void callMe(int calls) { if (calls > 0) System.out.println(”Hello”); int fewercalls = calls – 1; callMe(fewercalls); } DCS – SWC
Recursion Calling methods like this is often called recursion The previous example could easily be rewritten as a ”traditional” loop, and would even be more efficient However, quite a lot of problems can be solved very elegantly by recursion DCS – SWC
Recursion Example: the factorial function The factorial function F(n) is defined as: F(n) = n × (n-1) × (n-2) × … × 2 × 1 But you could also define F(n) as: F(n) = n × F(n-1) DCS – SWC
Recursion public void factorial(int n) { int result = 1; for (int val = 1; val <= n; val++) result = result * val; } return result DCS – SWC
Recursion public void factorial(int n) { if (n <= 1) return 1; else return (n * factorial(n-1)); } DCS – SWC
Thinking recursively Thinking in terms of recursion may seem quite confusing at first However, one should try not to think about how it works in detail Think in terms of how a problem can be solved, by solving ”simpler” versions of the same problem DCS – SWC
Thinking recursively Solving a problem by recursion: Control step: Does the problem have a simple solution? Division step: Split the problem into a simpler problem, plus a residual Solution step: Solve the simpler problem Combination step: Combine the solution to the simpler problem with the residual, in order to solve the original problem DCS – SWC
Thinking recursively Solving the factorial function by recursion: Control step: Is n < 1? If so, the result is 1 Division step: Original problem: F(n) Simpler problem: F(n-1) Residual: n DCS – SWC
Thinking recursively Solving the factorial function by recursion: Solution step: Solve F(n-1) (go to top…) Combination step: Combine by multiplying F(n-1) with n DCS – SWC
Thinking recursively public void factorial(int n) { if (n <= 1) return 1; else return (n * factorial(n-1)); } Control Step Division Step Solution Step Combination Step DCS – SWC
Thinking recursively A slightly harder problem is string permutations: Given a string of text, find all possible permutations of the characters in the string A string of length n will have n! different permutations DCS – SWC
Thinking recursively The string ”cat” has 3! = 6 permutations: ”cat” ”cta” ”act” ”atc” ”tac” ”tca” DCS – SWC
Thinking recursively Solving string permutations by recursion: Control step: Does the string have length 1? If so, the result is the string itself DCS – SWC
Thinking recursively Solving string permutations by recursion: Division step: For each character c in the string: Let c be the residual Remove c from the original string. The resulting string is then the simpler problem DCS – SWC
Thinking recursively Solving string permutations by recursion: Solution step: For each string S generated during the division step: Find all permutations of S DCS – SWC
Thinking recursively Solving string permutations by recursion: Combination step: For each string S generated during the solution step: Combine S with the residual character c, by adding c to the front of S (permutation = c + S) Add the permutation to the result set DCS – SWC
Thinking recursively Solving string permutation by recursion is not trivial… …but try to write an algorithm for string permutation without using recursion! Trust that it works! When there is a simple solution to simple inputs, and the problem can be solved by solving it for simpler inputs, it will work! DCS – SWC
Recursive helper methods It is sometimes easier to solve a more general problem by recursion Example: How to find a palindrome (a string which is equal to its own reverse) Possible interface to a Sentence class: Sentence(String theSentence) boolean isPalindrome() DCS – SWC
Recursive helper methods public boolean isPalindrome() { int len = text.length(); if (len < 2) return true; if ((text.substring(0,1).equals(text.substring(len-1,len))) Sentence newSen = new Sentence(text.substring(1,len-1)); return newSen.isPalindrome(); } else return false; DCS – SWC
Recursive helper methods Previous implementation works, but is somewhat inefficient We create a lot of Sentence objects Let us include a helper method, that checks if a substring is a palindrome: boolean isPalindrome(int start, int end) DCS – SWC
Recursive helper methods public boolean isPalindrome(int start, int end) { int len = end – start; if (len < 2) return true; if ((text.substring(start,start+1).equals( text.substring(end-1,end))) return isPalindrome(start+1,end-1); else return false; } DCS – SWC
Recursive helper methods Finally, implement original method by using the helper method: public boolean isPalindrome() { return isPalindrome(0, lext.length() – 1); } DCS – SWC
Efficiency of recursion Recursion is a very elegant principle, but not always the correct strategy… Can result in very inefficient algorithms, if care is not taken Common pitfall is to calculate identical values over and over DCS – SWC
Efficiency of recursion Example: Calculating Fibonacci numbers Fib(1) = 1 Fib(2) = 1 Fib(n) = Fib(n-1) + Fib(n-2) Looks like a recursive solution is a no-brainer… DCS – SWC
Efficiency of recursion public long fib(int n) { if (n <= 2) return 1; else return (fib(n-1) + fib(n-2)); } DCS – SWC
Efficiency of recursion Method does work, but is very inefficient We calculate same values over and over Fib(n) Fib(n-1) Fib(n-2) Fib(n-2) Fib(n-3) DCS – SWC
Recursion summary Recursion is a powerful and elegant tool for algorithm development Many algoritms are very easy to under-stand, if you understand recursion No silver bullet – recursive algorithms can be very slow Always consider (iterative) alternatives DCS – SWC