Download chapter 1 - CSUDH Computer Science

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
CHAPTER 17
RECURSION
CHAPTER 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
•
•
•
•
Triangle Numbers
Compute the area of a triangle of width n
Assume each [] square has an area of 1
Also called the nth triangle number
Example --The third triangle number is 6
[]
[] []
[] [] []
public class Triangle
{
public Triangle(int aWidth)
{
width = aWidth;
• Outline of Triangle }
public int getArea()
Class
{
...
}
private int width;
}
• Base case: Width 1
Handling Triangle
– The triangle consists of a single square -- area is 1
– Add the code to getArea method for width 1
public int getArea()
{
if (width == 1) return 1;
}
• General case:
– Assume we know the area of the smaller,
colored triangle
– Area of larger triangle can be calculated as:
smallerArea + width
– To get the area of the smaller triangle
o make a smaller triangle and ask it for
its area
Triangle smallerTriangle =
new Triangle(width - 1);
int smallerArea =
smallerTriangle.getArea();
[]
[] []
[] [] []
[] [] [] []
Completed getArea method
• The code
• That method makes a smaller
public int getArea()
triangle of width 2
{
– It calls getArea on that triangle
if (width == 1) return 1;
• That method makes a
Triangle smallerTriangle =
new Triangle(width - 1);
smaller triangle of width 1
int smallerArea =
• It calls getArea on that
smallerTriangle.getArea();
triangle
return smallerArea + width;
– That method returns 1
• Computing the area of a
– The method returns smallerArea
triangle with width 4
+ width = 1 + 2 = 3
– getArea method makes a • The method returns smallerArea +
smaller triangle of width 3
width = 3 + 3 = 6
– It calls getArea on that
• The method returns smallerArea +
triangle
width = 6 + 4 = 10
}
Recursion
• A recursive computation solves a problem by
using the solution
of 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 <= 0
• Add this line to the getArea method
if (width <= 0)
return 0;
File 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:
@param aWidth the width (and
height) of the triangle
13: */
14: public Triangle(int aWidth)
15: {
16:
width = aWidth;
17: }
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
/**
Computes the area of the triangle.
@return the area
*/
public int getArea()
{
if (width <= 0) return 0;
if (width == 1) return 1;
Triangle smallerTriangle = new
Triangle(width - 1);
28:
int smallerArea =
smallerTriangle.getArea();
29:
return smallerArea + width;
30: }
31:
32: private int width;
33: }
TriangleTest.java
01: import javax.swing.JOptionPane;
02:
03: public class TriangleTest
04: {
05: public static void main(String[] args)
06: {
07:
String input = JOptionPane.showInputDialog("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: }
Permutations of a String
• Design a class that lists all permutations of a string
• A permutation is a rearrangement of the letters
• The string "eat" has six permutations:
“eat”, “eta”, “aet”, “aet”, “tea”, “tae”
• Public Interface of PermutationGenerator
class PermutationGenerator
{
public PermutationGenerator(String s) { . . . }
public String nextPermutation() {. . . }
public boolean hasMorePermutations() { . . . }
}
File 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.nextPermutation());
12: }
13: }
To 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
• nextPermutaion
method returns one permutation at a
time
• PermutationGenerator remembers its state
o The string we are permuting (word)
o Position of the current character (current)
o PermutationGenerator of the substring (tailGenerator)
asks tailGenerator for its next
permutation and returns
• nextPermutation
word.charAt(current) + tailGenerator.nextPermutation();
Handling the Special Case
• When the tail generator runs out of
permutations, we need to:
o Increment the current position
o Compute the tail string that contains all
letters
except for the current one
o Make a new permutation generator for
the tail string
File PermutationGenerator.java
01: /** This class generates permutations of a word.
03: */
04: class PermutationGenerator
05: {
06: /** Constructs a permutation generator.
08:
@param aWord the word to permute
09: */
10: public PermutationGenerator(String aWord)
11: {
12:
word = aWord;
13:
current = 0;
14:
if (word.length() > 1)
15:
tailGenerator = new PermutationGenerator(word.substring(1));
16:
System.out.println("Generating " + word );
17: }
19: /**
20:
Computes the next permutation of the word.
21:
@return the next permutation
22: */
23: public String nextPermutation()
24: {
25:
if (word.length() == 1)
26:
{
current++; return word; }
31:
String r = word.charAt(current) + tailGenerator.nextPermutation();
33:
if (!tailGenerator.hasMorePermutations())
34:
{
35:
current++;
36:
if (current < word.length())
37:
{
38:
String tailString = word.substring(0, current)
39:
+ word.substring(current + 1);
40:
tailGenerator = new PermutationGenerator(tailString);
41:
}
42:
}
44:
return r;
45: }
47: /** Tests whether there are more permutations.
49:
@return true if more permutations are available
50: */
51: public boolean hasMorePermutations()
52: { return current < word.length();}
56: private String word;
57: private int current;
58: private PermutationGenerator tailGenerator;
59: }
Recursive 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
Recursive
Helper
Method
public boolean isPalindrome(int start int end)
{
//separate case for substrings of length 0 or 1
if (start>=end) return true;
//get first and last character, converted to lowercase
char first = Character.toLowerCase(text.charAt(start));
char last = Character.toLowerCase(text.charAt(end));
}
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);
}
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);
Fibonacci 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
• The Efficiency of Recursion
• You can generate the Fibonacci series using either recursion or iteration
o Both are conceptually easy to understand and program
o Iterative solution is much faster
• Palindrome test can be implemented as either recursion or
iteration
o
o
Both are easy to program
Both run about the same speed
• Permutation generator can be solved using either recursion
or iteration
o
Recursive solution is dramatically easier to understand and
implement
o Both run at about the same speed
File
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.showInputDialog("E
nter n: ");
12:
int n = Integer.parseInt(input);
13:
14:
for (int i = 1; i <= n; i++)
15:
{
16:
int f = fib(i);
17:
System.out.println("fib(" + i +
") = " + f);
18:
}
19:
System.exit(0);
20: }
21:
22: /**
23:
Computes a Fibonacci number.
24:
@param n an integer
25:
@return the nth Fibonacci number
26: */
27: public static int fib(int n)
28: {
29:
if (n <= 2) return 1;
30:
else return fib(n - 1) + fib(n - 2);
31: }
32: }
Call Pattern of the Recursive
fib Method
File FibTrace.java
20: /**
01: import javax.swing.JOptionPane;
21:
Computes a Fibonacci number.
03: /** This program prints trace
messages that show how often the 22:
@param n an integer
05: recursive method for computing
23:
@return the nth Fibonacci number
Fibonacci numbers calls itself.
24: */
06: */
25: public static int fib(int n)
07: public class FibTrace
26: {
08: {
27:
System.out.println("Entering fib: n
09: public static void main(String[]
args)
= " + n);
10: {
28:
int f;
11:
String input =
29:
if (n <= 2) f = 1;
JOptionPane.showInputDialog("Ent
30:
else f = fib(n - 1) + fib(n - 2);
er n: ");
31:
System.out.println("Exiting fib: n =
12:
int n = Integer.parseInt(input);
"+n
14:
int f = fib(n);
+ " return value = " + f);
16:
System.out.println("fib(" + n + ") 32:
= " + f);
33:
return f;
17:
System.exit(0);
34: }
18: }
35: }
File FibLoop.java
19:
System.exit(0);
20: }
21:
01: import javax.swing.JOptionPane;
22: /**
03: /**
Computes a Fibonacci number.
04: This program computes Fibonacci 23:
numbers using an iterative
24:
@param n an integer
05: method.
25:
@return the nth Fibonacci number
06: */
26: */
07: public class FibLoop
27: public static double fib(int n)
08: {
28: {
09: public static void main(String[]
29:
if (n <= 2) return 1;
args)
30:
double fold = 1;
10: {
31:
double fold2 = 1;
11:
String input =
32:
double fnew = 1;
JOptionPane.showInputDialog("En 33:
for (int i = 3; i <= n; i++)
ter n: ");
{
12:
int n = Integer.parseInt(input); 34:
35:
fnew = fold + fold2;
13:
36:
fold2 = fold;
14:
for (int i = 1; i <= n; i++)
37:
fold = fnew;
15:
{
38:
}
16:
double f = fib(i);
return fnew;
17:
System.out.println("fib(" + i + 39:
40: }
") = " + f);
41: }
18:
}