Sunteți pe pagina 1din 33

Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S

183

Chapter 8: Recursion
Solutions

Multiple Choice True/False


Solutions Solutions
1. b 1. T
2. c 2. T
3. c 3. F
4. c 4. T
5. b 5. F
6. a 6. F
7. e 7. T
8. d 8. F
9. e 9. T
10. a 10. F

Short Answer Solutions


8.1.  Write a recursive definition of a valid Java identifier (see Chapter 1).
8.2.
A valid Java Identifier is a Java Letter followed by zero or more Java Identifier
Substrings.
A Java Identifier Substring consists of zero or more valid Java Letters or zero 
or more Java Digits.  
A Java Letter is any of the 26 English alphabetic characters in both uppercase 
and lowercase, the $ and the _ (underscore) characters, as well as alphabetic 
characters from other languages.  
A Java Digit includes the digits 0 through 9.

8.3. Write a recursive definition of xy (x raised to the power y), where x and y are integers and y > 0.
8.4.
If y = 0, then xy  = 1.

otherwise xy = x * x(y­1).

8.5. Write a recursive definition of i * j (integer multiplication), where i > 0. Define the multiplication process in 
terms of integer addition. For example, 4 * 7 is equal to 7 added to itself 4 times.
8.6.
If i = 1, then i * j = j

otherwise i * j = j + (i­1) * j

where “*” refers to recursive multiplication as defined here and would be 
provided by a method such as “recursiveMult (i,j)”.  To avoid confusing “*” with 
conventional multiplication, the definition could be rewritten as

If i = 1, then recursiveMult (i,j) = j

otherwise, recursiveMult (i,j) = j + recursiveMult (i, j­1)

© 2011 Pearson Education


S 184 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

8.7. Write a recursive definition of the Fibonacci numbers. The Fibonacci numbers are a sequence of integers, 
each of which is the sum of the previous two numbers. The first two numbers in the sequence are 0 and 1. 
Explain why you would not normally use recursion to solve this problem.
8.8.
    Fib(0) = 0

    Fib(1) = 1
    Fib(j) = Fib(j­1) + Fib(j­2), j > 1
    
You would not normally use recursion to solve this problem since a Fibonacci 
number less than Fib(j­1) would be calculated at least twice in order to 
calculate Fib(j).   The recalculation of each such number would lead to the 
further recalculation of other Fibonacci numbers with the accompanying 
inefficiency.

8.9. Modify the method that calculates the sum of the integers between 1 and N shown in this chapter. Have the 
new version match the following recursive definition: The sum of 1 to N is the sum of 1 to (N/2) plus the sum 
of (N/2 + 1) to N. Trace your solution using an N of  7.
8.10.

public int sum (int num)
{
   int result;
   if (num == 1)
      result =  num;
   else
   {
      int half = num/2;
      int span = num ­ half;  // span is used to "shift" upper range
      result = sum(half) + sum(span) + (half * span);
   }
   return result;
}

8.11. Write a recursive method that returns the value of N! (N factorial) using the definition given in this chapter. 
Explain why you would not normally use recursion to solve this problem.
8.12.
public int factorial (int num)
{
     int result;

     if (num == 1)
        result = 1;
     else
        result = num * factorial (num ­ 1);

     return result;
}
You would not normally use recursion to solve this problem because it can be done
more efficiently using iteration and because the recursive solution it no more 
intuitive than the iterative solution.

8.13. Write a recursive method to reverse a string. Explain why you would not normally use recursion to solve this 
problem.
8.14.
public String reverse (String text)
{

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
185

   if (text.length() == 1)
      return text;
   else
   {
      String result;
      result = text.charAt(text.length() ­ 1)
         + reverse (text.substring(0, text.length()­1));

      return result;
   }
}

8.15. Design or generate a new maze for the MazeSearch program in this chapter and rerun the program. Explain 
the processing in terms of your new maze, giving examples of a path that was tried but failed, a path that was 
never tried, and the ultimate solution.
8.16.
A new maze could be generated with nested for loops which randomly place either a
1 or a 0 in each cell of a two­dimensional array.  Since the likelihood of 
generating a maze with a solution is generally low, subsequent mazes could be 
generated using a while loop until a maze with a solution is generated.

A maze with a solution could be hard­coded with the following statement:

private int [][] grid = { {1,0,1,0,1,1,1,1,1},
{1,0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0,1},
{1,1,1,0,1,0,1,0,1},
{0,0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0,1},
{1,0,1,0,1,0,1,0,1},
{1,0,1,1,1,1,1,0,1} };

After the search arrives at position (5,0), it attempts position (6,0).  
Encountering a 0 causes this path to fail.  It then attempts position (5,1) which
succeeds.  Subsequently, position (6,1) fails and position (5,2) succeeds.  
Because the maze is traversed successfully from position (5,2), no attempt is 
ever made to find a path from position (4,1)

The solution is marked with 7s.

7 0 1 0 1 1 7 7 7 
7 0 1 0 1 0 7 0 7 
7 0 1 0 1 0 7 0 7 
7 0 1 0 1 0 7 0 7 
7 0 1 0 1 0 7 0 7 
7 7 7 0 1 0 7 0 7 
0 0 7 0 1 0 7 0 7 
1 0 7 0 1 0 7 0 7 
1 0 7 0 1 0 7 0 7 
1 0 7 0 1 0 7 0 7 
1 0 7 7 7 7 7 0 7 

8.17. Annotate the lines of output of the SolveTowers program in this chapter to show the recursive steps.
8.18.
Move one disk from 1 to 2 // called with numDisks = 1
Move one disk from 1 to 3 // called with numDisks = 2
Move one disk from 2 to 3 // called with numDisks = 1
Move one disk from 1 to 2 // called with numDisks = 3
Move one disk from 3 to 1 // called with numDisks = 1
Move one disk from 3 to 2 // called with numDisks = 2

© 2011 Pearson Education


S 186 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

Move one disk from 1 to 2 // called with numDisks = 1
Move one disk from 1 to 3 // called with numDisks = 4 
Move one disk from 2 to 3 // called with numDisks = 1
Move one disk from 2 to 1 // called with numDisks = 2
Move one disk from 3 to 1 // called with numDisks = 1
Move one disk from 2 to 3 // called with numDisks = 3
Move one disk from 1 to 2 // called with numDisks = 1
Move one disk from 1 to 3 // called with numDisks = 2
Move one disk from 2 to 3 // called with numDisks = 1

Note the symmetry about the line where a call is made with numDisks = 4.

8.19. Produce a chart showing the number of moves required to solve the Towers of Hanoi puzzle using the 
following number of disks: 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, and 25.

Disks Moves

2:  3
3: 7
4: 15
5: 31
6: 63
7: 127
8: 255
9: 511
10: 1023
15: 32767
20: 1,048,575
25: 33,554,431

8.20. Describe a strategy for choosing a pivot value in quick sort so that the list will always be partitioned into two 
equal halves. Does your strategy change the time efficiency of quick sort?

In order to partition the list into two equal halves, the pivot value would have 
to be the median of the list. One way to find the median is the sort the list 
using insertion sort and take the value in the middle of the list. This would 
certainly affect the time efficiency!

8.21. How many line segments are used to construct a Koch snowflake of order N? Produce a chart showing the 
number of line segments that make up a Koch snowflake for orders 1 through 9.
8.22.
    A Koch snowflake of order N has 3(4N­1) line segments.

    Order Line Segments
    1: 3
    2: 12
    3: 48
    4: 192
    5: 768
    6: 3072
    7: 12,288
    8: 49,152
    9: 196,608

Programming Project Solutions

8.1 PalindromeTester
//********************************************************************
//  PalindromeTester.java       Author: Lewis/Loftus/Cocking

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
187

//
//  Solution to Programming Project 8.1
//
//  Modifies code from Chapter 3 to use recursion to identify a 
//  palindrome
//********************************************************************

import java.util.Scanner;

public class PalindromeTester {
   private String testString;
   
   public PalindromeTester(String test)
   {
      testString = convertString(test);
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Converts a string to correct format; removes all characters
   //  except for number and digits
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   private String convertString(String str)
   {
      StringBuffer convertedString = new StringBuffer();
      
      // convert string to lowercase, remove punctuation and whitespace
      for (int i = 0; i<str.length(); i++)
      {
         char c = str.charAt(i);
         c = Character.toLowerCase(c);
         if (Character.isLetterOrDigit(c))
            convertedString.append(c);
      }
      /* 
         String.substring(first, last) includes first char up to but not
         including last char.  Adding a dummy character on the end of the
         string prevents an ArrayIndexOutOfBounds exception when the 
isPalindrome()
         methods uses String.substring() to access the entire string
      */
      convertedString.append('*');

      return convertedString.toString();
   }
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Determines if the string is a palindrome.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public boolean isPalindrome()
   {
      return testPalindrome(0, testString.length()­1);
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Method determines if the string is a palindrome by
   //  recursively testing smaller substrings of the string.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   private boolean testPalindrome(int subStringStart, int subStringEnd)
   {
      // base case
      if (subStringEnd ­ subStringStart <= 1)
         return true;

© 2011 Pearson Education


S 188 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

      // compare the first and last characters
      if (testString.charAt(subStringStart) != testString.charAt(subStringEnd­
1))
         return false;
      
      // first and last equal, try smaller substring
      testPalindrome(subStringStart+1, subStringEnd­1);
      return true;
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Tests strings to see if they are palindromes.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public static void main (String args[]) 
    {
      String str, another = "y";
      Scanner scan = new Scanner (System.in);

      while (another.equalsIgnoreCase("y"))
      {
         System.out.println ("Enter a potential palindrome:");
         str = scan.nextLine();

         PalindromeTester p = new PalindromeTester(str);
         
         if (p.isPalindrome())
            System.out.println ("That string IS a palindrome.");
         else
            System.out.println ("That string is NOT a palindrome.");

         System.out.println();
         System.out.print ("Test another palindrome (y/n)? ");
         another = scan.nextLine();
      }
    }
}

8.2 DivisorCalc
//********************************************************************
//  DivisorCalc.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.2
//
//  Contains a static method to calculate the greatest common 
//  divisor of two positive integers.
//********************************************************************

public class DivisorCalc {

    public static int gcd(int num1, int num2)
    {
        if (num2 % num1 == 0) 
           return num1;
        else
           return gcd(num2, num1 % num2);
    }
}

8.3 Maze

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
189

//********************************************************************
//  Maze.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.3
//
//  Represents a maze of characters. The goal is to get from the
//  top left corner to the bottom right, following a path of 1s.
//  Prints the path of the final solution as it is discoverd.
//********************************************************************

public class Maze
{
   private final int TRIED = 3;
   private final int PATH = 7;

   private int[][] maze = { {1,1,1,0,1,1,0,0,0,1,1,1,1},
                            {1,0,1,1,1,0,1,1,1,1,0,0,1},
                            {0,0,0,0,1,0,1,0,1,0,1,0,0},
                            {1,1,1,0,1,1,1,0,1,0,1,1,1},
                            {1,0,1,0,0,0,0,1,1,1,0,0,1},
                            {1,0,1,1,1,1,1,1,0,1,1,1,1},
                            {1,0,0,0,0,0,0,0,0,0,0,0,0},
                            {1,1,1,1,1,1,1,1,1,1,1,1,1} };

   private int[][] grid;
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Creates a working copy of the maze to compute the final solution.
   //  The original maze is not modified.  Calls traverse to recursively
   //  traverse the maze.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 
   public boolean traverseMaze (int row, int column)
   {
      // make copy
      grid = new int[maze.length][maze[0].length];
      for (int i = 0; i < maze.length; i++)
         for (int j = 0; j < maze[i].length; j++)
            grid[i][j] = maze[i][j];
      
      return traverse(row, column);
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Attempts to recursively traverse the maze. Inserts special
   //  characters indicating locations that have been tried and that
   //  eventually become part of the solution.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   private boolean traverse (int row, int column)
   {
      boolean done = false;
      
      if (valid (row, column))
      {
         grid[row][column] = TRIED;  // this cell has been tried

         if (row == grid.length­1 && column == grid[0].length­1)
            done = true;  // the maze is solved
         else
         {
            done = traverse (row+1, column);     // down
            if (!done)

© 2011 Pearson Education


S 190 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

               done = traverse (row, column+1);  // right
            if (!done)
               done = traverse (row­1, column);  // up
            if (!done)
               done = traverse (row, column­1);  // left
         }

         if (done)  // this location is part of the final path
         {   
            grid[row][column] = PATH;
            System.out.println("[" + row +  "], [" + column + "]");
         }
      }
      
      return done;
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Determines if a specific location is valid.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   private boolean valid (int row, int column)
   {
      boolean result = false;
 
      // check if cell is in the bounds of the matrix
      if (row >= 0 && row < grid.length &&
          column >= 0 && column < grid[row].length)

         //  check if cell is not blocked and not previously tried
         if (grid[row][column] == 1)
            result = true;

      return result;
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Returns the maze as a string.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public String toString ()
   {
      String result = "\n";

      for (int row=0; row < maze.length; row++)
      {
         for (int column=0; column < maze[row].length; column++)
            result += maze[row][column] + "";
         result += "\n";
      }

      return result;
   }
}

8.3 MazeSearch
//********************************************************************
//  MazeSearch.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.3
//
//  Demonstrates recursion.
//********************************************************************

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
191

public class MazeSearch
{
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Creates a new maze, prints its original form, attempts to
   //  solve it, and prints out its final form.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public static void main (String[] args)
   {
      Maze labyrinth = new Maze();
      
      System.out.println (labyrinth);
      
      System.out.println("\nTraversal path [row],[column]");
      
      if (labyrinth.traverseMaze (0, 0))
         System.out.println ("The maze was successfully traversed!");
      else
         System.out.println ("There is no possible path.");

      System.out.println (labyrinth);
   }
}

8.4 Maze3D
//********************************************************************
//  Maze3D.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.4
//
//  Represents a 3D maze of characters. The goal is to get from the
//  top left near corner to the bottom right far corner, following a path of 
1s.
//  Prints the path of the final solution as it is discoverd.
//********************************************************************

public class Maze3D
{
   private final int TRIED = 3;
   private final int PATH = 7;

   private int[][][] maze;

   private int[][][] grid;
   
   public Maze3D(int[][][] newMaze)
   {
      maze = newMaze;
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Creates a working copy of the maze to compute the final solution.
   //  The original maze is not modified.  Calls traverse to recursively
   //  traverse the maze.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 
   public boolean traverseMaze (int row, int column, int page)
   {
      // make copy of maze
      grid = new int[maze.length][maze[0].length][maze[0][0].length];
      for (int i = 0; i < maze.length; i++)
         for (int j = 0; j < maze[i].length; j++)

© 2011 Pearson Education


S 192 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

            for (int k = 0; k < maze[i][j].length; k++)
               grid[i][j][k] = maze[i][j][k];
      
      return traverse(row, column, page);
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Attempts to recursively traverse the maze. Inserts special
   //  characters indicating locations that have been tried and that
   //  eventually become part of the solution.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   private boolean traverse (int row, int column, int page)
   {
      boolean done = false;
      
      if (valid (row, column, page))
      {
         grid[row][column][page] = TRIED;  // this cell has been tried

         if (row == grid.length­1 && column == grid[0].length­1 && page == 
grid[0][0].length­1)
            done = true;  // the maze is solved
         else
         {
            done = traverse (row+1, column, page);     // down
            if (!done)
               done = traverse (row, column+1, page);  // right
            if (!done)
               done = traverse (row, column, page+1);  // forward
            if (!done)
               done = traverse (row­1, column, page);  // up
            if (!done)
               done = traverse (row, column­1, page);  // left
            if (!done)
               done = traverse (row, column, page­1); // back
         }

         if (done)  // this location is part of the final path
         {   
            grid[row][column][page] = PATH;
            System.out.println("[" + row +  "], [" + column + "], [" + page + 
"]");
         }
      }
      
      return done;
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Determines if a specific location is valid.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   private boolean valid (int row, int column, int page)
   {
      boolean result = false;
 
      // check if cell is in the bounds of the matrix
      if (row >= 0 && row < grid.length &&
          column >= 0 && column < grid[row].length
            && page >= 0 && page < grid[row][column].length)

         //  check if cell is not blocked and not previously tried

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
193

         if (grid[row][column][page] == 1)
            result = true;

      return result;
   }
}

8.4 Maze3Dsearch
//********************************************************************
//  Maze3DSearch.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.4
//
//  Creates a random 3D maze and attempts to solve it.  Repeats until 
//  a maze is solved and prints out the traversal steps.
//********************************************************************

import java.util.Random;

public class Maze3DSearch {
   private static final int MAX_SIZE = 10;
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Generates a random 3D maze
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­   
   public static int[][][] generateRandom3DMaze()
   {
      Random gen = new Random();
      
      int[][][] maze = new int[MAX_SIZE][MAX_SIZE][MAX_SIZE];
      
      for (int i = 0; i < MAX_SIZE; i++)
         for (int j = 0; j < MAX_SIZE; j++)
            for (int k = 0; k < MAX_SIZE; k++)
            {
               if (gen.nextBoolean())
                  maze[i][j][k] = 1;
               else
                  maze[i][j][k] = 0;
            }
               
      return maze;
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Creates a random maze and attempts to solve it.  Repeats until 
   //  a maze is solved and prints out the traversal steps
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public static void main(String[] args)
   {
      boolean done = false;
      int numMazes = 0;
      while (!done)
      {
         Maze3D labyrinth = new Maze3D(Maze3DSearch.generateRandom3DMaze());
         numMazes++;

         if (labyrinth.traverseMaze (0, 0, 0))
         {
            System.out.println ("The maze was successfully traversed!");
            System.out.println("Num mazes generated : " + numMazes);

© 2011 Pearson Education


S 194 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

            done = true;
         }
      }
   }
}

8.5 MirroredPictures
//********************************************************************
//  MirroredPictures.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.5
//
//  Demonstrates the use of recursion.
//********************************************************************

import java.applet.Applet;
import java.awt.*;

public class MirroredPictures extends Applet 
{
   private final int APPLET_WIDTH = 320;
   private final int APPLET_HEIGHT = 320;
   private final int MIN = 20;  // smallest picture size

   private Image world, everest, goat;

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Loads the images.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public void init()
   {
      world = getImage (getDocumentBase(), "world.gif");
      everest = getImage (getDocumentBase(), "everest.gif");
      goat = getImage (getDocumentBase(), "goat.gif");

      setSize (APPLET_WIDTH, APPLET_HEIGHT);
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Draws the three images, then calls itself recursively.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public void drawPictures (int x, int y, int size, Graphics page)
   {
      page.drawImage (everest, x, y + size/2, size/2, size/2, this);
      page.drawImage (goat, x + size/2, y, size/2, size/2, this);
      page.drawImage (world, x, y, size/2, size/2, this);

      if (size > MIN)
         drawPictures (x + size/2, y + size/2, size/2, page);
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Performs the initial call to the drawPictures method.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public void paint (Graphics page)
   {
      drawPictures (0, 0, APPLET_WIDTH, page);
   }
}

8.6 NonAttackingQueens

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
195

//********************************************************************
//  NonAttackingQueens.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.6
//
//  A recursive program that solves the Non­attacking Queens problem.
//********************************************************************

public class NonAttackingQueens {

    int[] queens;   // Queen i is always placed in row i.  The
                    // column is variable.
                    // queens[i] represents the column of the ith row 
                    // where the ith queen is
    
    final int NUM_QUEENS = 8;
 
    public NonAttackingQueens()
    {
        queens = new int[NUM_QUEENS];
    }

    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    //  Returns true if a queen queenNumber can be placed in column 
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 
    boolean canPlace(int queenNumber, int column)
    {
        for (int row = 0; row < queenNumber; row++) // check all rows above 
queenNumber row
        {

            if (queens[row] == column) // in the same column
                return false;
            if (Math.abs(queens[row] ­ column) == Math.abs(row ­ 
queenNumber)) // same diagonal
                return false;
        }
        return true;
    }
    
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    //  Starting with the row represented by queenNumber, find all correct 
    //  placements in the row and below the row.
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public void solve(int queenNumber)
    {
        for (int column = 0; column < NUM_QUEENS; column++)  // iterate through
all columns
        {
            if (canPlace(queenNumber, column)) // queen can be placed in 
current column
            {
                queens[queenNumber] = column;  // place queen in current column

                if (queenNumber + 1 >= NUM_QUEENS) // solved
                    printSolution();
                else    // keep looking
                    solve(queenNumber + 1);
            }
        }
    }

© 2011 Pearson Education


S 196 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    //  Computes and displays all solutions to the problem
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­    
    public void showSolutions()
    {
        solve(0);  // start with the first row
    }
    
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    //  Prints a grid showing the postion of the queens on the chessboard.  
    //  Queen = X
    //  Empty space = O
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­    
    private void printSolution()
    {
        int column;
        for (int row=0; row<NUM_QUEENS; row++)
        {
            for (column = 0; column<NUM_QUEENS; column++)
                if (queens[row] == column)
                    System.out.print(" X");
                else 
                    System.out.print(" 0");
            System.out.print("\n");
        }
        System.out.println("\n­­­­­­­­­­­­­­­­­­­­­­­");

    }
    
    public static void main (String args[]) {
        new NonAttackingQueens().showSolutions();
    }
}

8.7 BlurbGenerator
//********************************************************************
//  BlurbGenerator.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.7
//
//  Generates random Blurbs using recursion
//********************************************************************
import java.util.Scanner;
import java.util.Random;

public class BlurbGenerator {
    Random chooser;
    
    public BlurbGenerator() 
    {
      chooser = new Random();
    }
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Recursively generates a random Whoozit 'y' string.
   //  A Whoozit 'y' string is zero or more 'y's
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    private String getWhoozitYs()
    {
       StringBuffer y = new StringBuffer();

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
197

       
       boolean stop = chooser.nextBoolean();
       if (!stop)
          y.append(getWhoozitYs());
       else     
         return y.toString();
       
       y.append("y");
       return y.toString();
    }
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Generates a random Whoozit.
   //  A Whoozit is the character 'x' followed by zero or more 'y's
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    private String getWhoozit()
    {
       StringBuffer whoozit = new StringBuffer();
       whoozit.append("x");
       whoozit.append(getWhoozitYs());
       
       return whoozit.toString();
    }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Generates a random Whatzit.
   //  A Whatzit is a 'q' followed by either a 'z' or a 'd', followed
   //  by a Whoozit.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    private String getWhatzit()
    {
       StringBuffer whatzit = new StringBuffer();
       whatzit.append("q");
       boolean z = chooser.nextBoolean();
       if (z)
          whatzit.append("z");
       else
          whatzit.append("d");
       
       whatzit.append(getWhoozit());
       
       return whatzit.toString();
       
    }
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Recursively generates a string of one or more Whatzits.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­   
    private String getMultipleWhatzits()
    {
       StringBuffer whatzits = new StringBuffer();
       
       whatzits.append(getWhatzit());
       boolean stop = chooser.nextBoolean();
       if (!stop)
          whatzits.append(getMultipleWhatzits());
       else     
         return whatzits.toString();
       
       return whatzits.toString();
    }

© 2011 Pearson Education


S 198 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

    
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Generates a random Blurb.
   //  A Blurb is a Whoozit followed by one or more Whatzits
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public String generateBlurb()
    {
       StringBuffer blurb = new StringBuffer();
       blurb.append(getWhoozit());
       blurb.append(getMultipleWhatzits());
       
       return blurb.toString();
    }
    
    public static void main(String args[])
    {
       BlurbGenerator blurbs = new BlurbGenerator();
       Scanner scan = new Scanner (System.in);
       
       System.out.println("How many blurbs would you like? ");
       int numBlurbs = scan.nextInt();
       if (numBlurbs < 0)
          numBlurbs = 0;
       for (int i=0; i<numBlurbs; i++)
         System.out.println("Blurb : " + blurbs.generateBlurb());
    }
}

8.8 BlurbParser
//********************************************************************
//  BlurbParser.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.8
//
//  Parses a string using recursion and determines if
//  the string is a valid Blurb,
//********************************************************************

import java.util.Scanner;

public class BlurbParser {

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Parses a Whatzit.
   //  A Whatzit is a 'q' followed by either a 'z' or a 'd', followed
   //  by a Whoozit.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    private boolean parseWhatzit(String aString)
    {
      if (aString.length() >= 3)  // long enough
         if (aString.charAt(0) ==  'q')
            if (aString.charAt(1) == 'z' || aString.charAt(1) == 'd')
               return parseWhoozit(aString.substring(2));
      return false;  // does not begin with 'q'
    }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Parses a Whoozit.
   //  A Whoozit is the character 'x' followed by zero or more 'y's
   //  A Whoozit may be followed by a Whatzit

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
199

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    private boolean parseWhoozit(String aString)
    {
       int charIndex = 0;
       if (aString.length() < 1)
          return false;  // too short
       if (aString.charAt(charIndex++) == 'x')
       {
          while (charIndex < aString.length() && aString.charAt(charIndex) == 
'y')
             charIndex++;
          if (charIndex >= aString.length())  // done
             return true;
          if (aString.charAt(charIndex) == 'q')  // valid Whatzit
             return parseWhatzit(aString.substring(charIndex));
          else
             return false; // not followed by a Whatzit
       }
       else
          return false; // does not begin with 'x'
    }
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Parses a Blurb.
   //  A Blurb is a Whoozit followed by one or more Whatzits
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­    
    public boolean isABlurb(String aString)
    {
          return parseWhoozit(aString);
    }
    
    public static void main (String args[]) 
    {
       BlurbParser parser = new BlurbParser();
       Scanner scan = new Scanner (System.in);
       
       String another = "y";
       while (another.equalsIgnoreCase("y"))
       {
          System.out.println("Enter a Blurb:");
          String blurb = scan.nextLine();
          if (parser.isABlurb(blurb))
            System.out.println(blurb + " IS a valid Blurb");
          else
             System.out.println(blurb + " is NOT a valid Blurb");
          System.out.println("Parse another Blurb (y/n/)?");
          another = scan.nextLine();
       }
    }

8.9 PascalTriangle
//********************************************************************
//  PascalTriangle.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.9
//
//  Determines and prints the Nth line of Pascal's Triangle
//********************************************************************

© 2011 Pearson Education


S 200 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

import java.util.Scanner;

public class PascalTriangle {
    private int rowNumber;
    
    private int rowCount;
    private int[] newRow;
    
    
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    //  Creates an new PascalTriangle
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­    
    public PascalTriangle()
    {
       rowNumber = 1;
    }
    
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    //  Creates a new PascalTriangle with the row number n
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public PascalTriangle(int n) 
    {
       setRow(n);
    }
    
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    //  Sets the row of the triangle to n.  If n is less than 1, sets
    //  row to 1
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 
    public void setRow(int n)
    {
       if (n < 1)
          rowNumber = 1;
       else
          rowNumber = n;
    }
    
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    //  Returns the row number setting
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public int getRow()
    {
       return rowNumber;
    }
    
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    //  Recursively computes successive rows of Pascal's triangle 
    //  until the Nth row (represented by the variable rowNumber) is
    //  reached.
    //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    private void expand(int[] row)
    {
       //base case
       if (rowCount >= rowNumber)
          return;
       newRow = new int[row.length+1];
       newRow[0] = 1;

       for (int i=1; i<row.length; i++)
          newRow[i] = row[i­1] + row[i];

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
201

       newRow[row.length] = 1;
       
       rowCount ++;
       expand(newRow);
       return;
    }
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Computes and returns the Nth row (represented by 
   //  the variable rowNumber) of Pascal's Triangle.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­    
   public int[] computeRow()
   {
      rowCount = 1;
      newRow = new int[rowCount];
      newRow[0] = 1;
      
      expand(newRow);
      return newRow;
   }

    public static void main (String args[]) 
    {
      String another = "y";
      Scanner scan = new Scanner (System.in);
      
      while (another.equalsIgnoreCase("y"))
      {
         System.out.println("Enter the line number to compute of Pascal's 
Triangle:");
         int row = scan.nextInt();
         PascalTriangle p = new PascalTriangle(row);
         int[] result = p.computeRow();
         System.out.println("Line " + p.getRow() + " of Pascal's Triangle");
         for (int i=0; i<result.length;i++)
            System.out.print(result[i] + " ");   
            
         System.out.println("\n\nAnother (y/n)?");
         another = scan.nextLine();
      }     
    }
}

8.10 RecursiveSorts
//********************************************************************
//  RecursiveSorts.java       Author: Lewis/Loftus/Cocking
//
//  Implements a quick sort of doubles
//********************************************************************

public class RecursiveSorts
{
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Sorts the specified array of doubles using quick sort.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public static void quickSort (double[] numbers)
   {
      doQuickSort(numbers, 0, numbers.length ­ 1);
   }
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Recursively sorts the portion of the given array beginning

© 2011 Pearson Education


S 202 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

   //  at start and ending at end.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   private static void doQuickSort (double[] numbers, int start, int end)
   {
      if (start < end)
      {
         int middle = partition(numbers, start, end);
         doQuickSort(numbers, start, middle);
         doQuickSort(numbers, middle + 1, end);
      }
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Partitions the array such that each value in [start, middle]
   //  is less than or equal to each value in [middle + 1, end].
   //  The index middle is determined in the procedure and returned.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   private static int partition (double[] numbers, int start, int end)
   {
      double pivot = numbers[(start + end) / 2];
      int i = start ­ 1;
      int j = end + 1;

      // As the loop progresses, the indices i and j move towards each other.
      // Elements at i and j that are on the wrong side of the partition are
      // exchanged. When i and j pass each other, the loop ends and j is
      // returned as the index at which the elements are partitioned around.
      while (true)
      {
         i = i + 1;
         while (numbers[i] < pivot)
            i = i + 1;

         j = j ­ 1;
         while (numbers[j] > pivot)
            j = j ­ 1;

         if (i < j)
         {
            double tmp = numbers[i];
            numbers[i] = numbers[j];
            numbers[j] = tmp;
         }
         else return j;
      }
   }
}

8.10 SortPrices
//********************************************************************
//  SortPrices.java       Author: Lewis/Loftus/Cocking
//
//  Sorts an array of prices using quick sort
//********************************************************************

public class SortPrices
{
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Creates an array of prices, sorts them, then prints them.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public static void main (String[] args)

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
203

   {
      double[] prices = {1.99, 2.45, 23.35, 0.25, 119.99, 5.55, 19.85};

      RecursiveSorts.quickSort (prices);

      for (int index = 0; index < prices.length; index++)
         System.out.print (prices[index] + "   ");

      System.out.println();
   }
}

8.11 Disk
//********************************************************************
//  Disk.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.11
//
//  Encapsulates a disk in the grapical Towers of Hanoi solution
//********************************************************************

import java.awt.Color;
import java.awt.Graphics;

class Disk 
{
   int diskSize;
   
   static final int HEIGHT = 20;
   static final int WIDTH_STEP = 20;
   static final int ARC_WIDTH = 5;
   static final int ARC_HEIGHT = 5;
  
   static final Color[] DISK_COLORS = {
                           Color.black,
                           Color.red,
                           Color.blue,
                           Color.yellow,
                           Color.green,
                           Color.orange,
                           Color.magenta,
                           Color.gray,
                           Color.pink 
                  };
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Creates a disk of specified size
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   Disk(int size)
   {
      diskSize = size;
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Returns the size of the disk
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   int getSize()
   {
        return diskSize;
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­

© 2011 Pearson Education


S 204 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

   //  Returns the width of the disk to be drawn on the screen
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   int getScreenWidth()
   {
       return diskSize * WIDTH_STEP;
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Returns the color of the disk as indexed in DISK_COLORS
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   Color getDiskColor()
   {
      return DISK_COLORS[diskSize % DISK_COLORS.length];
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Draws the disk using graphics context g.  Position x 
   //  represents the x coordinate of the center of the tower, 
   //  position y represents the top position of the disk on the tower
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   void draw(Graphics g, int x, int y)
   {
       int width = getScreenWidth();
       int diskX = x ­ width / 2;
       g.setColor(getDiskColor());
       g.fillRoundRect(diskX, y, width, HEIGHT, ARC_WIDTH, ARC_HEIGHT);
       g.setColor(Color.black);
       g.drawRoundRect(diskX, y, width, HEIGHT, ARC_WIDTH, ARC_HEIGHT);

   }

8.11 Tower
//********************************************************************
//  Tower.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.11
//
//  Encapsulates a tower in the grapical Towers of Hanoi solution
//********************************************************************

import java.util.Stack;
import java.awt.Color;
import java.awt.Graphics;

class Tower 
{
   Stack disks;
   int towerHeight;
   static final int WIDTH = 10;
   
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Creates a new tower, height should be set to the max number of
   //  disks the tower will hold.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public Tower(int height) 
   {
      disks = new Stack();
      towerHeight = height;

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
205

   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Adds disk to the top of the tower
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 
   void addDisk(Disk d)
   {
      disks.push(d);
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Removes the top disk from the tower
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   Disk removeDisk()
   {
      if (disks.empty())
          return null;
      else
        return (Disk)disks.pop();
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Draws the tower using graphics context g.  The coordinates (x,y)
   //  represent the bottom left corner of the tower
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­   
   void draw(Graphics g, int x, int y)
   {
      // draw tower
      int height = Disk.HEIGHT * towerHeight;
      g.setColor(Color.black);
      g.fillRect(x,y­height, WIDTH, height);
      
      // draw disks
      if (!disks.isEmpty())
      {
           // create a stack of disks in reverse order
           Stack temp = new Stack();
           while (!disks.empty())
                temp.push(disks.pop());
           
           // draw the disks
           int location = 1;
           int diskX = x + WIDTH / 2;
           while (!temp.isEmpty()) 
           {
               Disk d = (Disk)temp.pop();
               
               int diskY = y ­ Disk.HEIGHT * location;
               d.draw(g, diskX, diskY);

               // put disk back on stack
               disks.push(d);
               location ++;
           }
      }
   }
}

8.11 Move
//********************************************************************
//  Move.java       Author: Lewis/Loftus/Cocking

© 2011 Pearson Education


S 206 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

//
//  Solution to Programming Project 8.11
//
//  Encapsulates a disk move
//*********************************************************************

public class Move {

    private int from;
    private int to;
    

    public Move(int fromTower, int toTower) 
    {
        from = fromTower;
        to = toTower;
    }

    public String toString()
    {
        return "Move from tower " + from + " to tower " + to;
    }
    
    public int getFrom()
    {
        return from;
    }
    
    public int getTo()
    {
        return to;
    }
    
}

8.11 TowerFrame
//********************************************************************
//  TowerFrame.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.11
//
//  Main progrma to run the Graphical Towers of Hanoi
//********************************************************************

import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.event.*;
import java.awt.*;
import java.util.Hashtable;

public class TowerFrame extends JFrame{
    TowerPanel towerViewer;

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Sets up the main GUI
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public TowerFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        towerViewer = new TowerPanel(TowerPanel.DEFAULT_NUM_DISKS);
        getContentPane().add(towerViewer, BorderLayout.CENTER);

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
207

        // create listeners
        SliderListener sliderHandler = new SliderListener();
        ButtonListener buttonHandler = new ButtonListener();
        
        //create animation button panel
        JPanel animationButtonPanel = new JPanel();
        animationButtonPanel.setLayout(new GridLayout(1,2));
        
        JButton pause = new JButton("Pause Animation");
        pause.setName("pause");
        pause.addActionListener(buttonHandler);
        animationButtonPanel.add(pause);
        
        JButton start = new JButton("Resume Animation");
        start.setName("resume");
        start.addActionListener(buttonHandler);
        animationButtonPanel.add(start);        
        
        //create animation speed slider
        JSlider speed = new JSlider();
        speed.setName("speed");
        speed.setMinimum(TowerPanel.MIN_PAUSE_TIME);
        speed.setMaximum(TowerPanel.MAX_PAUSE_TIME);
        speed.setValue(TowerPanel.DEFAULT_PAUSE_TIME);
        speed.setBorder(new TitledBorder("Animation Speed"));
       
        // make label table
        Hashtable labelTable = new Hashtable();
        labelTable.put(new Integer(TowerPanel.MIN_PAUSE_TIME), new 
JLabel("Faster"));
        labelTable.put(new Integer(TowerPanel.MAX_PAUSE_TIME), new 
JLabel("Slower"));
       
        speed.setLabelTable(labelTable);
        speed.setPaintLabels(true);
        speed.addMouseListener(sliderHandler);

        // create options button panel
        JPanel buttonPanel = new JPanel();
        
        JButton animate = new JButton("Animate");
        animate.setName("animate");
        animate.addActionListener(buttonHandler);
        buttonPanel.add(animate);
        
        JButton user = new JButton("Let Me Try");
        user.setName("user");
        user.addActionListener(buttonHandler);
        buttonPanel.add(user);
        
        JButton reset = new JButton("Reset");
        reset.setName("reset");
        reset.addActionListener(buttonHandler);        
        buttonPanel.add(reset);
        
        JPanel controls = new JPanel();
        controls.setLayout(new BoxLayout(controls, BoxLayout.Y_AXIS));
        controls.add(buttonPanel);
        controls.add(speed);
        controls.add(animationButtonPanel);

© 2011 Pearson Education


S 208 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

        
        getContentPane().add(controls, BorderLayout.SOUTH);
        
        // make disk selector
        JSlider diskNum = new JSlider();
        diskNum.setName("disks");
        diskNum.setMinimum(TowerPanel.MIN_DISKS);
        diskNum.setMaximum(TowerPanel.MAX_DISKS);
        diskNum.setValue(TowerPanel.DEFAULT_NUM_DISKS);
        diskNum.setBorder(new TitledBorder("Disks"));
        diskNum.setMajorTickSpacing(1);
        diskNum.setPaintLabels(true);
        diskNum.setPaintTicks(true);
        diskNum.setSnapToTicks(true);
        diskNum.addMouseListener(sliderHandler); 
        
        getContentPane().add(diskNum, BorderLayout.NORTH);
        pack();
    }

    public static void main (String args[]) {
        new TowerFrame().show();
    }

    //********************************************************************
    //  Represents the mouse listener class for the sliders.
    //********************************************************************
    class SliderListener extends MouseAdapter
    {
      public void mouseReleased(MouseEvent event)
      {
          JSlider source = (JSlider)event.getSource();
          if (source.getName() == "speed")
            towerViewer.setPauseTime(source.getValue());
          else
              if (source.getName() == "disks")
                  towerViewer.setNumDisks(source.getValue());
      }
    }
    
    //********************************************************************
    //  Represents the button listener class for the buttons.
    //********************************************************************    
    class ButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            JButton source = (JButton)e.getSource();
            String name = source.getName();
            if (name == "reset")
                towerViewer.resetTowers();
            else
                if (name == "animate")
                    towerViewer.animate();
                else
                   if (name == "user")
                        towerViewer.userSolve();
                   else 
                        if (name == "pause")
                            towerViewer.stopTimer();

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
209

                        else 
                            if (name == "resume")
                                towerViewer.resumeTimer();
        }
    }
}

8.11 TowerPanel
//********************************************************************
//  TowerPanel.java       Author: Lewis/Loftus/Cocking
//
//  Solution to Programming Project 8.11
//
//  Controls the graphical display of the Towers of Hanoi
//********************************************************************

import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;

public class TowerPanel extends JPanel {
    TowersOfHanoi towerEngine;
    Tower[] towers;
    
    int numDisks;
    int pauseTime;
    int firstTower;
  //  boolean solved;
    boolean userSolve;
    boolean firstTowerSelected;

    ArrayList solution;
    Timer animationTimer;
    
    static final int MIN_PAUSE_TIME = 50;
    static final int MAX_PAUSE_TIME = 1500;
    static final int DEFAULT_PAUSE_TIME = 900;
    static final int MIN_DISKS = 1;
    static final int MAX_DISKS = 8;
    static final int DEFAULT_NUM_DISKS = 4;
    static final int NUM_TOWERS = 3;
    
    final String TRY_AGAIN_MESSAGE = "Incorrect move\n Try Again?";
    final String SOLVED_MESSAGE = "Congratulations!\nYou solved the puzzle!";

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Creates a new tower panel to diplay the Towers of Hanoi
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public TowerPanel(int disks) 
    {
      numDisks = disks;
      pauseTime = DEFAULT_PAUSE_TIME;
      solution = new ArrayList();
      userSolve = false;
      firstTowerSelected = false;
      
      towers = new Tower[NUM_TOWERS];
      for (int i=0; i<NUM_TOWERS; i++)
          towers[i] = new Tower(numDisks);

© 2011 Pearson Education


S 210 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

      
      //add sized disks to first tower
      for (int i=numDisks; i>0; i­­)
        towers[0].addDisk(new Disk(i));

      towerEngine = new TowersOfHanoi(numDisks);

      setBackground(Color.white);
      
      addMouseListener(new TowerSelectListener());
    }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Overrides JPanels getPreferredSize().
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ 
    public Dimension getPreferredSize() 
    {
      // panel width is length of largest disk * num towers + 2 width step 
between towers
      int panelWidth = MAX_DISKS * Disk.WIDTH_STEP * NUM_TOWERS + 2 * 
Disk.WIDTH_STEP + NUM_TOWERS;
      // panel height 1.2 as tall as largest towers
      int panelHeight = Disk.HEIGHT * MAX_DISKS; 
      panelHeight = Math.round(1.2f * (float)panelHeight);
      
      return new Dimension(panelWidth, panelHeight);
    }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Draws the Towers of Hanoi.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
     public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        int towerSpacing = getSize().width /  NUM_TOWERS;
        
        int towerX = towerSpacing/2 ­ Tower.WIDTH/2;
        int towerY = getSize().height;
        
        for (int i=0; i<NUM_TOWERS; i++)
        {
            towers[i].draw(g, towerX, towerY);
            towerX += towerSpacing;
        }
    }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Sets the amount of time in milliseconds to pause between each
   //  animation step.  If in animation mode, resets the animation
   //  timer
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public void setPauseTime(int time)
    {
        pauseTime = time;
        if (animationTimer == null)
            return;
        if (userSolve)  // no animation
            return;
        // update animation speed
        if (!solution.isEmpty() && animationTimer.isRunning()) 
        {

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
211

            stopTimer();
            animationTimer = new Timer(pauseTime, new UpdateAnimation());
            animationTimer.start();
        }
    }
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Sets the number of disks and resets the puzzle.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­   
    public void setNumDisks(int num)
    {
        numDisks = num;
        stopTimer();            // stop any animation
        userSolve = false;      // stop any user solution
        resetTowers();
    }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Animates the current solution.  Stops any user solution
   //  If the solution is empty, resets the towers.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
     public void animate()
    {
        userSolve = false; // stop user solution
        stopTimer();  // temporarily stop timer
        if (solution.isEmpty())
            resetTowers();
                                // start new timer
        animationTimer = new Timer(pauseTime, new UpdateAnimation());
        animationTimer.start();
    }
    
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Allows a user to step­by­step solve the puzzle.
   //  Stops any animation and starts user solution mode.
   //  If solution is empty, resets the towers.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public void userSolve()
    {
        stopTimer();  // stop animation
        if (solution.isEmpty())
            resetTowers(); // start over
        userSolve = true;  // check for mouse motion
    }
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Resets the towers to current settings.
   //  Creates new towers, tower engine, solution, and 
   //  redraws the screen.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public void resetTowers() 
    {
      towers = new Tower[NUM_TOWERS];
      for (int i=0; i<NUM_TOWERS; i++)
          towers[i] = new Tower(numDisks);
      
      for (int i=numDisks; i>0; i­­)
        towers[0].addDisk(new Disk(i));
      
      towerEngine = new TowersOfHanoi(numDisks);

© 2011 Pearson Education


S 212 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

      solution = towerEngine.getSolution();
      repaint();
    }
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Stops the animation timer.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public void stopTimer()
    {
        if (animationTimer == null)
            return;
        if (animationTimer.isRunning())
            animationTimer.stop();
    }
    
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Resumes the animation timer, stops any user solutions
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
    public void resumeTimer()
    {
        if (animationTimer == null)
            return;
        if (!animationTimer.isRunning())  // get new settings and restart
        {
           userSolve = false;
           animationTimer = new Timer(pauseTime, new UpdateAnimation());
           animationTimer.start();
        }
    }
    
    //********************************************************************
    //  Represents the listener class for the animation timer.
    //********************************************************************
    class UpdateAnimation implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            if (!solution.isEmpty()) 
            {
                Move nextMove = (Move)solution.remove(0);
                Disk d = towers[nextMove.getFrom()].removeDisk();
                towers[nextMove.getTo()].addDisk(d);
                repaint();
            }
        }
    }
    
    //********************************************************************
    //  Represents the mouse listener class for the panel.  Used in
    //  the user solve mode.
    //********************************************************************    
    class TowerSelectListener extends MouseAdapter
    {
        public void mousePressed(MouseEvent e)
        {
            if (!userSolve)
                return;
            if (solution.isEmpty())
                return;

            int towerSpacing = getSize().width /  NUM_TOWERS;                

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
213

            // determine tower choosen
            int selectedTower;
            int xValue = e.getX();
            if (xValue < towerSpacing)
                selectedTower = 0;
            else
                if (xValue < 2 * towerSpacing)
                    selectedTower = 1;
                else
                    selectedTower = 2;
            if (!firstTowerSelected)
            {
                firstTower = selectedTower;
                firstTowerSelected = true;
            }
            else
            {
                // determine if valid move was selected
                firstTowerSelected = false;
                
                Move currentMove = (Move)solution.get(0);
                // if currentMove correct  . . .
                if (currentMove.getFrom() == firstTower &&
                        currentMove.getTo() == selectedTower)
                {
                    solution.remove(0);
                    Disk d = towers[currentMove.getFrom()].removeDisk();
                    towers[currentMove.getTo()].addDisk(d);
                    repaint();
                }
                else // incorrect move
                {
                    int result =JOptionPane.showConfirmDialog(null, 
                                TRY_AGAIN_MESSAGE, 
                                "", 
                                JOptionPane.YES_NO_OPTION,
                                JOptionPane.WARNING_MESSAGE);
                    // show solution anyway?
                    if (result != JOptionPane.YES_OPTION) 
                    {
                        solution.remove(0);
                        Disk d = towers[currentMove.getFrom()].removeDisk();
                        towers[currentMove.getTo()].addDisk(d);
                        repaint();
                    }
                        
                }
            }
            // display solved message
            if (solution.isEmpty())
            {
                JOptionPane.showMessageDialog(null,
                                        SOLVED_MESSAGE,
                                        "",
                                        JOptionPane.INFORMATION_MESSAGE);
            }
            
        }
    }
}

© 2011 Pearson Education


S 214 Lewis/Loftus/Cocking: 3/e Chapter 8
Solutions

8.11 TowersofHanoi
//********************************************************************
//  TowersOfHanoi.java       Author: Lewis/Loftus/Cocking
//
//  Represents the classic Towers of Hanoi puzzle.
//********************************************************************

import java.util.ArrayList;

public class TowersOfHanoi
{
   private int totalDisks;
 
   ArrayList moves;

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Sets up the puzzle.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public TowersOfHanoi (int numDisks)
   {
      totalDisks = numDisks;
      moves = new ArrayList();
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Performs the initial call to moveTower to solve the puzzle.
   //  Moves the disks from tower 1 to tower 3 using tower 2.
   //  Returns an ArrayList of the moves made.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   public ArrayList getSolution()
   {
      moveTower (totalDisks, 0, 2, 1);
      return moves;
   }
   
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Moves the specified number of disks from one tower to another
   //  by moving a subtower of n­1 disks out of the way, moving one
   //  disk, then moving the subtower back. Base case of 1 disk.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   private void moveTower (int numDisks, int start, int end, int temp)
   {
      if (numDisks == 1)
         moveOneDisk (start, end);
      else
      {
         moveTower (numDisks­1, start, temp, end);
         moveOneDisk (start, end);
         moveTower (numDisks­1, temp, end, start);
      }
   }

   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   //  Stores instructions to move one disk from the specified start
   //  tower to the specified end tower.
   //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
   private void moveOneDisk (int start, int end)
   {
        moves.add(new Move(start, end));
   }

© 2011 Pearson Education


Lewis/Loftus/Cocking, 3/e: Chapter 8 Solutions S
215

AP-Style Multiple Choice


Solutions
1. C
2. A
3. A
4. D
5. C
6. D

AP-Style Free Response Solution

8.1
a.
// precondition: n > 0
public static int factorial (int n)
{
if (n == 1)
return 1;
else
return n * factorial(n-1);
}

b.
// precondition: exp >= 0
public static int power (int base, int exp)
{
if (exp == 0)
return 1;
else
return base * power(base, exp-1);
}

c.
// precondition: a has size at least 1
public static void triple (int[] a)
{
tripleHelp (a, 0);
}

// triples the elements from k to a.length-1


private static void tripleHelp (int[] a, int k)
{
a[k] = a[k] * 3;
if (k < a.length-1)
tripleHelp(a, k+1);
}

© 2011 Pearson Education

S-ar putea să vă placă și