Title: RECURSION
1CHAPTER 17
2CHAPTER GOALS
- To learn about the method of recursion
- To understand the relationship between recursion
and iteration - To analysis problems that are much easier to
solve by recursion than by iteration - To learn to think recursively
- To be able to use recursive helper methods
- To understand when the use of recursion affects
the efficiency of an algorithm
3Triangle Numbers
- Compute the area of a triangle of width n
- Assume each square has an area of 1
- Also called the nth triangle number
4The Third Triangle Number
- The third triangle number is 6
-
-
-
5Outline of Triangle Class
- public class Triangle
-
- public Triangle(int aWidth)
-
- width aWidth
-
- public int getArea()
-
- ...
-
- private int width
-
6Handling Triangle of Width 1
- The triangle consists of a single square
- Its area is 1
- Add the code to getArea method for width 1
- public int getArea()
-
- if (width 1) return 1
-
7Handling General Case
-
- Assume we know the area of the smaller, colored
triangle - Area of larger triangle can be calculated
assmallerArea width - To get the area of the smaller triangle
- make a smaller triangle and ask it for its
areaTriangle smallerTriangle new
Triangle(width - 1) - int smallerArea smallerTriangle.getArea()
8Completed getArea method
- public int getArea()
-
- if (width 1) return 1
- Triangle smallerTriangle new Triangle(width -
1) - int smallerArea smallerTriangle.getArea()
return smallerArea width -
9Computing the area of a triangle with width 4
- getArea method makes a smaller triangle of width
3 - It calls getArea on that triangle
- That method makes a smaller triangle of width 2
- It calls getArea on that triangle
- That method makes a smaller triangle of width 1
- It calls getArea on that triangle
- That method returns 1
- The method returns smallerArea width 1 2
3 - The method returns smallerArea width 3 3
6 - The method returns smallerArea width 6 4
10
10Recursion
- A recursive computation solves a problem by using
the solutionof the same problem with simpler
input - For recursion to terminate, there must be
special cases for the simplest inputs. - To complete our Triangle example, we must handle
width lt 0 - Add this line to the getArea method
- if (width lt 0) return 0
11File Triangle.java
- 01 /
- 02 A triangular shape composed of stacked
unit squares like this - 03
- 04
- 05
- 06 . . .
- 07 /
- 08 public class Triangle
- 09
- 10 /
- 11 Constructs a triangular shape
- 12 _at_param aWidth the width (and height) of
the triangle - 13 /
- 14 public Triangle(int aWidth)
- 15
- 16 width aWidth
- 17
12- 18
- 19 /
- 20 Computes the area of the triangle.
- 21 _at_return the area
- 22 /
- 23 public int getArea()
- 24
- 25 if (width lt 0) return 0
- 26 if (width 1) return 1
- 27 Triangle smallerTriangle new
Triangle(width - 1) - 28 int smallerArea smallerTriangle.getAre
a() - 29 return smallerArea width
- 30
- 31
- 32 private int width
- 33
13TriangleTest.java
- 01 import javax.swing.JOptionPane
- 02
- 03 public class TriangleTest
- 04
- 05 public static void main(String args)
- 06
- 07 String input JOptionPane.showInputDial
og("Enter width") - 08 int width Integer.parseInt(input)
- 09 Triangle t new Triangle(width)
- 10 int area t.getArea()
- 11 System.out.println("Area " area)
- 12
- 13
14Permutations of a String
- Design a class that will list all permutations of
a string - A permutation is a rearrangement of the letters
- The string "eat" has six permutations "eat"
"eta" "aet" "tea" "tae"
15Public Interface of PermutationGenerator
- class PermutationGenerator
-
- public PermutationGenerator(String s) . . .
public String nextPermutation() . . . - public boolean hasMorePermutations() . . .
16File PermutationGeneratorTest.java
- 01 /
- 02 This program tests the permutation
generator. - 03 /
- 04 public class PermutationGeneratorTest
- 05
- 06 public static void main(String args)
- 07
- 08 PermutationGenerator generator
- 09 new PermutationGenerator("eat")
- 10 while (generator.hasMorePermutations())
- 11 System.out.println(generator.nextPerm
utation()) - 12
- 13
17To Generate All Permutations
- Generate all permutations that start with 'e' ,
then 'a' then 't' - To generate permutations starting with 'e', we
need to find all permutations of "at" - This is the same problem with simpler inputs.
- Use recursion
18To Generate All Permutations
- nextPermutaion method returns one permutation at
a time - PermutationGenerator remembers its state
- The string we are permuting (word)
- Position of the current character (current)
- PermutationGenerator of the substring
(tailGenerator) - nextPermutation asks tailGenerator for its next
permutation and returnsword.charAt(current)
tailGenerator.nextPermutation()
19Handling the Special Case
- When the tail generator runs out of permutations,
we need to - Increment the current position
- Compute the tail string that contains all
letters except for the current one - Make a new permutation generator for the tail
string
20File PermutationGenerator.java
- 01 /
- 02 This class generates permutations of a
word. - 03 /
- 04 class PermutationGenerator
- 05
- 06 /
- 07 Constructs a permutation generator.
- 08 _at_param aWord the word to permute
- 09 /
- 10 public PermutationGenerator(String aWord)
- 11
- 12 word aWord
- 13 current 0
- 14 if (word.length() gt 1)
- 15 tailGenerator new
PermutationGenerator(word.substring(1)) - 16 System.out.println("Generating " word
) - 17
21- 18
- 19 /
- 20 Computes the next permutation of the
word. - 21 _at_return the next permutation
- 22 /
- 23 public String nextPermutation()
- 24
- 25 if (word.length() 1)
- 26
- 27 current
- 28 return word
- 29
- 30
- 31 String r word.charAt(current)
tailGenerator.nextPermutation() - 32
- 33 if (!tailGenerator.hasMorePermutations()
) - 34
- 35 current
- 36 if (current lt word.length())
22- 39 word.substring(current 1)
- 40 tailGenerator new
PermutationGenerator(tailString) - 41
- 42
- 43
- 44 return r
- 45
- 46
- 47 /
- 48 Tests whether there are more
permutations. - 49 _at_return true if more permutations are
available - 50 /
- 51 public boolean hasMorePermutations()
- 52
- 53 return current lt word.length()
- 54
- 55
- 56 private String word
- 57 private int current
23Recursive Helper Method
- The public boolean method isPalindrone calls
helper method isPalindrome(int start, int end) - Helper method skips over matching letter pairs
and non-letters and calls itself recursively
24Recursive Helper Method
- public boolean isPalindrome(int start int end)
-
-
- //separate case for substrings of length 0 or
1 - if (startgtend) return true
-
- //get first and last character, converted to
lowercase - char first Character.toLowerCase(text.charAt(
start)) - char last Character.toLowerCase(text.charAt(e
nd)) -
- if ((Character.isLetter(first)
Character.isLetter(last)) -
- if (first last)
-
- //test substring that doesn't contain
the matching letters - return isPalindrome(start 1, end -1)
-
25- else
- return false
-
- else if (!Character.isLetter(last))
-
- //test substring that doesn't contain last
character - return isPalindrome(start, end -1)
-
- else
-
- //test substring that doesn't contain first
character - return isPalindrome(start 1, end)
26Using Mutual Recursion
- Problem to compute the value of arithmetic
expressions such as - 3 4 5 (3 4) 5 1 - (2 - (3 - (4 -
5)))
27Syntax Diagram for Evaluating and Expression
28Syntax Tree for Two Expressions
29Mutually Recursive Methods
- Implement 3 methods that call each other
recursively - getExpressionValue
- getTermValue
- getFactorValue
30File Evaluator.java
- 01 /
- 02 A class that can compute the value of an
arithmetic expression. - 03 /
- 04 public class Evaluator
- 05
- 06 /
- 07 Constructs an evaluator.
- 08 _at_param anExpression a string containing
the expression - 09 to be evaluated.
- 10 /
- 11 public Evaluator(String anExpression)
- 12
- 13 tokenizer new ExpressionTokenizer(anEx
pression) - 14
- 15
- 16 /
- 17 Evaluates the expression.
31- 18 _at_return the value of the expression.
- 19 /
- 20 public int getExpressionValue()
- 21
- 22 int value getTermValue()
- 23 boolean done false
- 24 while (!done)
- 25
- 26 String next tokenizer.peekToken()
- 27 if ("".equals(next)
"-".equals(next)) - 28
- 29 tokenizer.nextToken()
- 30 int value2 getTermValue()
- 31 if ("".equals(next)) value
value value2 - 32 else value value - value2
- 33
- 34 else done true
- 35
- 36 return value
32- 38
- 39 /
- 40 Evaluates the next term found in the
expression. - 41 _at_return the value of the term.
- 42 /
- 43 public int getTermValue()
- 44
- 45 int value getFactorValue()
- 46 boolean done false
- 47 while (!done)
- 48
- 49 String next tokenizer.peekToken()
- 50 if ("".equals(next)
"/".equals(next)) - 51
- 52 tokenizer.nextToken()
- 53 int value2 getFactorValue()
- 54 if ("".equals(next)) value
value value2 - 55 else value value / value2
- 56
33- 58
- 59 return value
- 60
- 61
- 62 /
- 63 Evaluates the next factor found in the
expression. - 64 _at_return the value of the factor.
- 65 /
- 66 public int getFactorValue()
- 67
- 68 int value
- 69 String next tokenizer.peekToken()
- 70 if ("(".equals(next))
- 71
- 72 tokenizer.nextToken()
- 73 value getExpressionValue()
- 74 next tokenizer.nextToken() //
read ")" - 75
- 76 else
34- 78 return value
- 79
- 80
- 81 private ExpressionTokenizer tokenizer
- 82
35File ExpressionTokenizer.java
- 01 /
- 02 This class breaks up a string describing
an expression - 03 into tokens numbers, parentheses, and
operators - 04 /
- 05 public class ExpressionTokenizer
- 06
- 07 /
- 08 Constructs a tokenizer.
- 09 _at_param anInput the string to tokenize
- 10 /
- 11 public ExpressionTokenizer(String anInput)
- 12
- 13 input anInput
- 14 start 0
- 15 end 0
- 16 nextToken()
- 17
36- 18
- 19 /
- 20 Peeks at the next token without
consuming it. - 21 _at_return the next token or null if there
are no more tokens - 22 /
- 23 public String peekToken()
- 24
- 25 if (start gt input.length()) return
null - 26 else return input.substring(start,
end) - 27
- 28
- 29 /
- 30 Gets the next token and moves the
tokenizer to the - 31 following token.
- 32 _at_return the next token or null if there
are no more tokens - 33 /
- 34 public String nextToken()
- 35
- 36 String r peekToken()
37- 38 if (start gt input.length()) return r
- 39 if (Character.isDigit(input.charAt(start
))) - 40
- 41 end start 1
- 42 while (end lt input.length()
Character.isDigit(input.charAt(end))) - 43 end
- 44
- 45 else
- 46 end start 1
- 47 return r
- 48
- 49
- 50 private String input
- 51 private int start
- 52 private int end
- 53
38File EvaluatorTest.java
- 01 import javax.swing.JOptionPane
- 02
- 03 /
- 04 This program tests the expression
evaluator. - 05 /
- 06 public class EvaluatorTest
- 07
- 08 public static void main(String args)
- 09
- 10 String input JOptionPane.showInputDial
og("Enter an expression") - 11 Evaluator e new Evaluator(input)
- 12 int value e.getExpressionValue()
- 13 System.out.println(input ""
value) - 14 System.exit(0)
- 15
- 16
39Fibonacci Sequence
- Fibonacci sequence is a sequence of numbers
defined by f1 1 f2 1 fn fn-1
fn-2 - First ten terms 1, 1, 2, 3, 5, 8, 13, 21, 34,
55
40The Efficiency of Recursion
- You can generate the Fibonacci series using
either recursion or iteration - Both are conceptually easy to understand and
program - Iterative solution is much faster
41The Efficiency of Recursion
- Palindrome test can be implemented as either
recursion or iteration - Both are easy to program
- Both run about the same speed
42The Efficiency of Recursion
- Permutation generator can be solved using either
recursion or iteration - Recursive solution is dramatically easier to
understand and implement - Both run at about the same speed
43File FibTest.java
- 01 import javax.swing.JOptionPane
- 02
- 03 /
- 04 This program computes Fibonacci numbers
using a recursive - 05 method.
- 06 /
- 07 public class FibTest
- 08
- 09 public static void main(String args)
- 10
- 11 String input JOptionPane.showInputDial
og("Enter n ") - 12 int n Integer.parseInt(input)
- 13
- 14 for (int i 1 i lt n i)
- 15
- 16 int f fib(i)
- 17 System.out.println("fib(" i ")
" f)
44- 18
- 19 System.exit(0)
- 20
- 21
- 22 /
- 23 Computes a Fibonacci number.
- 24 _at_param n an integer
- 25 _at_return the nth Fibonacci number
- 26 /
- 27 public static int fib(int n)
- 28
- 29 if (n lt 2) return 1
- 30 else return fib(n - 1) fib(n - 2)
- 31
- 32
45Call Pattern of the Recursive fib Method
46File FibTrace.java
- 01 import javax.swing.JOptionPane
- 02
- 03 /
- 04 This program prints trace messages that
show how often the - 05 recursive method for computing Fibonacci
numbers calls itself. - 06 /
- 07 public class FibTrace
- 08
- 09 public static void main(String args)
- 10
- 11 String input JOptionPane.showInputDial
og("Enter n ") - 12 int n Integer.parseInt(input)
- 13
- 14 int f fib(n)
- 15
- 16 System.out.println("fib(" n ") "
f) - 17 System.exit(0)
47- 18
- 19
- 20 /
- 21 Computes a Fibonacci number.
- 22 _at_param n an integer
- 23 _at_return the nth Fibonacci number
- 24 /
- 25 public static int fib(int n)
- 26
- 27 System.out.println("Entering fib n "
n) - 28 int f
- 29 if (n lt 2) f 1
- 30 else f fib(n - 1) fib(n - 2)
- 31 System.out.println("Exiting fib n "
n - 32 " return value " f)
- 33 return f
- 34
- 35
48File FibLoop.java
- 01 import javax.swing.JOptionPane
- 02
- 03 /
- 04 This program computes Fibonacci numbers
using an iterative - 05 method.
- 06 /
- 07 public class FibLoop
- 08
- 09 public static void main(String args)
- 10
- 11 String input JOptionPane.showInputDial
og("Enter n ") - 12 int n Integer.parseInt(input)
- 13
- 14 for (int i 1 i lt n i)
- 15
- 16 double f fib(i)
- 17 System.out.println("fib(" i ")
" f) - 18
49- 19 System.exit(0)
- 20
- 21
- 22 /
- 23 Computes a Fibonacci number.
- 24 _at_param n an integer
- 25 _at_return the nth Fibonacci number
- 26 /
- 27 public static double fib(int n)
- 28
- 29 if (n lt 2) return 1
- 30 double fold 1
- 31 double fold2 1
- 32 double fnew 1
- 33 for (int i 3 i lt n i)
- 34
- 35 fnew fold fold2
- 36 fold2 fold
- 37 fold fnew
50