360 likes | 668 Views
Recursion - see Recursion. Recursion. We know that: We can define classes We can define methods on classes Mehtods can call other methods But…can a method call itself…?. Recursion. public void callMe() { System.out.println(”Hello”); callMe(); }. Recursion.
E N D
Recursion • We know that: • We can define classes • We can define methods on classes • Mehtods can call other methods • But…can a method call itself…? RHS – SWC
Recursion publicvoid callMe() { System.out.println(”Hello”); callMe(); } RHS – 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 RHS – SWC
Recursion publicvoid callMe(int calls) { if (calls > 0) { System.out.println(”Hello”); int fewercalls = calls – 1; callMe(fewercalls); } } RHS – 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 RHS – 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) RHS – SWC
Recursion publicvoid factorial(int n) { int result = 1; for (int val = 1; val <= n; val++) { result = result * val; } return result } RHS – SWC
Recursion publicvoid factorial(int n) { if (n <= 1) return 1; else return (n * factorial(n-1)); } RHS – 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 RHS – 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 RHS – 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 RHS – 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 RHS – SWC
Thinking recursively publicvoid factorial(int n) { if (n <= 1) return 1; else return (n * factorial(n-1)); } Control Step Division Step Solution Step Combination Step RHS – 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 RHS – SWC
Thinking recursively • The string ”cat” has 3! = 6 permutations: • ”cat” • ”cta” • ”act” • ”atc” • ”tac” • ”tca” RHS – SWC
Thinking recursively • Solving string permutations by recursion: • Control step: • Does the string have length 1? If so, the result is the string itself RHS – 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 RHS – SWC
Thinking recursively • Solving string permutations by recursion: • Solution step: • For each string S generated during the division step: • Find all permutations of S RHS – 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 RHS – 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! RHS – 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() RHS – SWC
Recursive helper methods publicboolean 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; } RHS – 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) RHS – SWC
Recursive helper methods publicboolean 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; } RHS – SWC
Recursive helper methods • Finally, implement original method by using the helper method: publicboolean isPalindrome() { return text.isPalindrome(0, lext.length() – 1); } RHS – 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 RHS – 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… RHS – SWC
Efficiency of recursion publiclong fib(int n) { if (n <= 2) return 1; else return (fib(n-1) + fib(n-2)); } RHS – 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) RHS – 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 RHS – SWC