lec12 - 1.00 Lecture 12 Recursion Reading for next time Big...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: 1.00 Lecture 12 Recursion Reading for next time: Big Java: sections 11.1-11.4 Recursion • Recursion is a divide-and-conquer (or divide-andcombine) approach to solving problems: method Recurse(Arguments) if (SmallEnough(Arguments)) // Termination return Answer else // “Divide” Identity= Combine( SomeFunc(Arguments), Recurse(SmallerArguments)) return Identity // “Combine” • If you can write a problem as the combination of smaller problems, you can implement it as a recursive algorithm in Java 1 Finding maximum of array Assume we can only find max of 2 numbers at a time. Suppose we want to find the max of a set of numbers, say 8 of them. 35 74 32 92 53 28 50 62 Our recursive max method calls itself: max(0,7) 92 max(0,3) max(0,1) 74 92 max(2,3) 92 62 max(4,7) max(4,5) 53 max(6,7) 62 Code for maximum method public class public class MaxRecurse { static void main(String args) public static void main(String args) { int AData= {35, 74, 32, 92, 53, 28, 50, 62}; int AData= {35, 74, 32, 92, 53, 28, 50, 62}; System.out.println println("Max: maxArray(0, 7, AData)); System.out.println("Max: " + maxArray(0, 7, AData)); } static combine(int public static int combine(int a, int b) { (a >= b) return a; if (a >= b) return a; return b; else return b; } static maxArray( int Arr) public static int maxArray( int i, int j, int Arr) { (j <= 1 ) Small enough if ( (j ­ i) <= 1) { // Small enough (Arr Arr[j] >= Arr[i]) if (Arr[j] >= Arr[i]) Arr[j]; return Arr[j]; else Arr[i]; return Arr[i]; } Divide and combine else // Divide and combine (combine(maxArray (combine(maxArray(i, (i+j)/2, Arr), return (combine(maxArray(i, (i+j)/2, Arr), j, Arr))); maxArray((i+j)/2+1, j, Arr))); } } 2 Maximum code with more output public class MaxRecurse2 { public class MaxRecurse2 static void main(String args) public static void main(String args) { int AData= {35, 74, 32, 92, 53, 28, 50, 62}; int AData= {35, 74, 32, 92, 53, 28, 50, 62}; System.out.println println("Main Max:" maxArray(0, 7, AData)); System.out.println("Main Max:" + maxArray(0, 7, AData)); } static combine(int public static int combine(int a, int b) { (a>=b) return a; if (a>=b) return a; return b; else return b; } static maxArray( int Arr) public static int maxArray( int i, int j, int Arr) { System.out.println println("Max(" "," ")"); System.out.println("Max(" + i + "," + j + ")"); (j <= 1) if ( (j ­ i) <= 1) { (Arr Arr[j] >= Arr[i]) Small enough if (Arr[j] >= Arr[i]) { // Small enough System.out.println println(" Arr[j]); System.out.println(" " + Arr[j]); Arr[j]; return Arr[j]; } else { System.out.println println(" Arr[i]); System.out.println(" " + Arr[i]); Arr[i]; return Arr[i]; } } Divide, combine else { // Divide, combine int aa= (combine(maxArray(i, (i+j)/2, Arr), aa= (combine(maxArray(i, (i+j)/2, Arr), (combine(maxArray j, Arr))); maxArray((i+j)/2+1, j, Arr))); System.out.println println("Max(" +i "," +j ")= "+ aa); System.out.println("Max(" +i + "," +j + ")= "+ aa); aa; return aa; }}} Exponentiation • Exponentiation, done ‘simply’, is inefficient – Raising x to y power can take y multiplications: • E.g., x7 = x * x * x * x * x * x * x – Successive squaring is much more efficient, but requires some care in its implementation – For example: x48 = ((((x * x * x)2) 2) 2) 2 uses 6 multiplications instead of 48 • Informally, simple exponentiation is O(n) – Squaring is O(lg n), because raising a number to the nth power take about lg n operations (base 2) • Lg(48)= Log2(48)= about 6 • 25 = 32; 26 = 64 – To find x1,000,000,000 , squaring takes 30 operations while the simple method takes 1,000,000,000! 3 Exponentiation cont. • Odd exponents take a little more effort: – x7 = x * (x*x*x)2 uses 4 operations instead of 7 – x9 = x * (x*x)2 )2 uses 4 operations instead of 9 • We can generalize these observations and design an algorithm that uses squaring to exponentiate quickly • Writing this with iteration and keeping track of odd and even exponents can be tricky • It is most naturally written as a recursive algorithm – We write a series of 3 identities and then implement them as a Java function! Exponentiation, cont. • Three identities: – x1 = x – x2n= xn * xn – x2n+1= x* x2n (small enough) (reduces problem) (reduces problem) 4 Exercise • Write pseudocode for exponentiation – Write your pseudocode on paper or Eclipse – Use the standard pattern: – You can write the identities as expressions; you don’t have to use a ‘Combine’ method • ‘Combine’ is usually just * or + or Math.max()… method Recurse(Arguments) if (SmallEnough(Arguments)) // Termination return Answer else // “Divide” Identity= Combine( SomeFunc(Arguments), Recurse(SmallerArguments)) return Identity // “Combine” How the recursion works x= 5, y= 9 ExpResult(5, 9) 5 * ExpResult (5, 8) = 1953125 square(ExpResult(5, 4)) = 390625 square(ExpResult(5, 2)) = 625 square(ExpResult(5, 1)) ExpResult(5, 1) = 25 =5 5 Exponentiation Exercise // Download Exponentiation class and complete it // Download Exponentiation class and complete it javax.swing.*; import javax.swing.*; class Exponentiation public class Exponentiation { static void main(String args) public static void main(String args) { int z; String input= JOptionPane.showInputDialog("Enter x"); input= JOptionPane.showInputDialog("Enter x"); Integer.parseInt Integer.parseInt(input); int x= Integer.parseInt(input); JOptionPane.showInputDialog("Enter y"); input= JOptionPane.showInputDialog("Enter y"); Integer.parseInt Integer.parseInt(input); int y= Integer.parseInt(input); expResult(x, y); z= expResult(x, y); System.out.println(x + " to " + y + " power is: " + z); System.out.println(x to power is: z); println } You can use handle large numbers. bit clumsy. // You can use BigInteger to handle large numbers. A bit clumsy. Exponentiation Exercise, p.2 public int static int expResult(int x, int y) { static expResult( result; // Write code when y is small enough Write code when is small enough Write code when we need to divide the problem further // Write code when we need to divide the problem further Add System.out.println System.out. desired to trace results // Add System.out.println as desired to trace results result; return result; } } 6 Recursion and iteration • It’s a tricky exercise to write the exponentiation iteratively – Try it if you have time and are interested! • It’s often easier to see a correct recursive implementation – Recursion is often closer to the underlying mathematics • There is a mechanical means to convert recursion to iteration, used by compilers and algorithm designers. It’s complex, and is used to improve efficiency. – Overhead of method calls is noticeable, and converting recursion to iteration within a method speeds up execution – Small or infrequently used methods can be left as recursive Exercise 1 • An example sequence is defined as: – q0 = 0 – qn = (1 + qn-1)1/3 • Write a recursive method to compute qn • Download Sequence1 (or type it from next page) – Main is written for you • Write method q() in class Sequence1. q() is a method in Sequence1, just like main() – The recursive method ‘signature’ is written also – The body of the recursive method follows the template: • If small enough, determine value directly • Otherwise, divide and combine – Use Math.pow(base,exponent) to take the cube root Math.pow Math.pow(base,exponent) • Remember to make the exponent 1.0/3.0, not 1/3 • Save/compile and run or debug it – Try n= 10, or n= 20 7 Download Code 1 javax.swing.*; import javax.swing.*; public class Sequence1 { class Sequence1 public static void main(String args) { static void main(String args) String input= JOptionPane.showInputDialog("Enter n"); input= JOptionPane. showInputDialog("Enter n"); Integer.parseInt Integer.parseInt(input); int n= Integer.parseInt(input); lastTerm= double lastTerm= q(n); System.out.println println("Last term: "+ lastTerm); System.out.println("Last term: "+ lastTerm); } static double q(int q( public static double q(int n) { Write your code here // Write your code here Put in System.out.printlns System.out. you return values // Put in System.out.printlns when you return values } Sample output: // Sample output: n: 0 answer: 0.0 n: 1 answer: 1.0 n: 2 answer: 1.2599210498948732 n: 3 answer: 1.3122938366832888 Exercise 2 • A second sequence is defined as: – – – – q0 = 0 q1 = 0 q2 = 1 qn = qn-3 + qn-2 for n >= 3 • Write a recursive method to compute qn • Download Sequence2 (or type it from next page) – Main is written for you • Write method q() in class Sequence2. q() is a method in Sequence2, just like main() – The recursive method ‘signature’ is written also – The body of the recursive method follows the template: • If small enough, determine value directly • Otherwise, divide and combine • Save/compile and run or debug it – Try n= 10, or n= 20 8 Download Code 2 javax.swing.*; import javax.swing.*; public class Sequence2 { class Sequence2 public static void main(String args) { static void main(String args) String input= JOptionPane.showInputDialog("Enter n"); input= JOptionPane. showInputDialog("Enter n"); Integer.parseInt Integer.parseInt(input); int n= Integer.parseInt(input); Call it for all i<=n (int 0; n; i++) for (int i= 0; i < n; i++) // Call it for all i<=n System.out.println println("i: "+ q: q(i)); System.out.println("i: "+ i + " q: " + q(i)); } static q(int public static int q(int n) { Write your code here // Write your code here } } Sample solution // Sample solution i: 0 q: 0 i: 1 q: 0 i: 2 q: 1 i: 3 q: 0 i: 4 q: 1 Exercise 3 • A pair of sequences is defined as: – x0 = 1; – y0 = 2; xn = xn/2 + yn/3 yn = xn/3 * yn/2 + 2 (Note the *, not +) • Write two recursive methods to compute xn and yn – Subscripts n/2 and n/3 use integer division • Download Sequence3 (or type it from next page) – Main is written for you • Methods x() and y() are methods in class Sequence3, just like main(). – The bodies of the recursive methods follow the template: • If small enough, determine value directly • Otherwise, divide and combine • Save/compile and run or debug it – Try n= 10, or n= 20 9 Download Code 3 javax.swing.*; import javax.swing.*; public class Sequence3 { class Sequence3 public static void main(String args) { static void main(String args) String input= JOptionPane.showInputDialog("Enter n"); input= JOptionPane. showInputDialog("Enter n"); Integer.parseInt Integer.parseInt(input); int n= Integer.parseInt(input); System.out.println println("i y"); System.out.println("i x y"); (int 1; <= n; i++) for (int i= 1; i <= n; i++) System.out.println println(i x(i) y(i)); System.out.println(i + " " + x(i) + " " + y(i)); } Write your methods for x(i) and y(i) here // Write your methods for x(i) and y(i) here } Sample solution // Sample solution ixy 134 256 14 3 7 14 20 4 9 20 20 5 9 20 10 ...
View Full Document

This note was uploaded on 11/29/2011 for the course CIVIL 1.00 taught by Professor Georgekocur during the Spring '05 term at MIT.

Ask a homework question - tutors are online