Recursion Based on slides by Alyssa Harding

Slides:



Advertisements
Similar presentations
Copyright 2006 by Pearson Education 1 Building Java Programs Chapter 12: Recursion.
Advertisements

1 Chapter 18 Recursion Dale/Weems/Headington. 2 Chapter 18 Topics l Meaning of Recursion l Base Case and General Case in Recursive Function Definitions.
Slides prepared by Rose Williams, Binghamton University Chapter 11 Recursion.
CHAPTER 10 Recursion. 2 Recursive Thinking Recursion is a programming technique in which a method can call itself to solve a problem A recursive definition.
CS212: DATASTRUCTURES Lecture 3: Recursion 1. Lecture Contents 2  The Concept of Recursion  Why recursion?  Factorial – A case study  Content of a.
CSE 143 Lecture 11 Recursive Programming reading: slides created by Marty Stepp and Hélène Martin
Building Java Programs Chapter 12 Lecture 12-2: recursive programming reading:
A Computer Science Tapestry 1 Recursion (Tapestry 10.1, 10.3) l Recursion is an indispensable technique in a programming language ä Allows many complex.
Slides prepared by Rose Williams, Binghamton University ICS201 Lecture 19 : Recursion King Fahd University of Petroleum & Minerals College of Computer.
Recursion Textbook chapter Recursive Function Call a recursive call is a function call in which the called function is the same as the one making.
Reading – Chapter 10. Recursion The process of solving a problem by reducing it to smaller versions of itself Example: Sierpinski’s TriangleSierpinski’s.
CS212: DATASTRUCTURES Lecture 3: Recursion 1. Lecture Contents 2  The Concept of Recursion  Why recursion?  Factorial – A case study  Content of a.
CSE 143 Lecture 13 Recursive Programming reading: slides created by Marty Stepp
Building Java Programs Chapter 12 Recursion Copyright (c) Pearson All rights reserved.
CSE 143 Lecture 10 Recursion reading: slides created by Marty Stepp and Hélène Martin
CSE 143 Lecture 9 Recursion slides created by Alyssa Harding
Recursion in Java The answer to life’s greatest mysteries are on the last slide.
CSE 143 Lecture 9: introduction to recursion reading: 12.1.
Building Java Programs Chapter 12: Recursive public/private pairs Chapter 13: Searching reading: 13.3.
Lecture 11 Recursion. A recursive function is a function that calls itself either directly, or indirectly through another function; it is an alternative.
Recursion Powerful Tool
Lecture 24: Recursion Building Java Programs: A Back to Basics Approach by Stuart Reges and Marty Stepp Copyright (c) Pearson All rights reserved.
Lecture 9: introduction to recursion reading: 12.1
Topic 6 Recursion.
Lecture 10: recursive programming reading:
Building Java Programs
Recursion
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Java Programming: Program Design Including Data Structures
Building Java Programs
Building Java Programs
Announcements Final Exam on August 17th Wednesday at 16:00.
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Building Java Programs
slides adapted from Marty Stepp and Hélène Martin
Adapted from slides by Marty Stepp, Stuart Reges & Allison Obourn.
Building Java Programs
slides created by Ethan Apter
Lecture 10: recursive programming reading:
CSE 143 Lecture 14 (A) More Recursive Programming
CSE 143 Lecture 11 Recursive Programming reading:
Cs212: DataStructures Computer Science Department Lab 3 : Recursion.
Building Java Programs
Recursion.
CSE 143 Lecture 14 More Recursive Programming; Grammars
CSE 143 Lecture 11 Recursive Programming slides created by Marty Stepp
slides created by Ethan Apter
slides created by Marty Stepp and Alyssa Harding
Recursion based on slides by Alyssa Harding
slides created by Ethan Apter
Basics of Recursion Programming with Recursion
Lecture 14: Strings and Recursion AP Computer Science Principles
Lecture 19: Recursion Building Java Programs: A Back to Basics Approach by Stuart Reges and Marty Stepp Copyright (c) Pearson All rights reserved.
slides created by Alyssa Harding
Building Java Programs
slides adapted from Marty Stepp and Hélène Martin
CSE 143 Lecture 13 Recursive Programming reading:
Building Java Programs
slides created by Alyssa Harding
CSE 143 Lecture 2 ArrayIntList, binary search
Generics, Stack, Queue Based on slides by Alyssa Harding
slides created by Ethan Apter
Building Java Programs
Lecture 10: recursive programming reading:
slides created by Ethan Apter and Marty Stepp
slides created by Marty Stepp
Building Java Programs
Recursion Chapter 12.
slides created by Alyssa Harding
Presentation transcript:

Recursion Based on slides by Alyssa Harding CSE 143 Lecture 13 Recursion Based on slides by Alyssa Harding

Recursion recursion: The definition of an operation in terms of itself. Solving a problem using recursion depends on solving smaller occurrences of the same problem. recursive programming: Writing methods that call themselves to solve problems recursively. An equally powerful substitute for iteration (loops) Particularly well-suited to solving certain types of problems

Why learn recursion? Many programming languages ("functional" languages such as Scheme, ML, and Haskell) use recursion exclusively (no loops) "cultural experience" - A different way of thinking of problems Can solve some kinds of problems better than iteration Leads to elegant, simplistic, short code (when used well) A key component of the rest of our assignments in CSE 143

Decimal Numbers vs. Binary Numbers Decimal Numbers (“Base 10”) 10 Possible Digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 Ex. With 3 digits we get: 10 * 10 * 10 different patterns (0-999) We interpret these patterns as follows: 34810 = 300 + 40 + 8 = 3 ×102 + 4 ×101 + 8×100 Binary Numbers (“Base 2”) 2 Possible Digits: 0, 1 Ex. With 3 digits we get: 2 * 2 * 2 different patterns (000-111) 1012 = 1 ×22 + 0 ×21 + 1×20 = 1 ×4 + 0 ×2 + 1×1 = 4 + 1 = 510 4

Binary Numbers A few Decimal numbers written in Binary: Decimal Binary Sum 0 × 20 1 1 × 20 2 10 1 × 21 + 0 × 20 3 11 1 × 21 + 1 × 20 4 100 1 × 22 + 0 × 21 + 0 × 20 5 101 1 × 22 + 0 × 21 + 1 × 20 6 110 1 × 22 + 1 × 21 + 0 × 20 7 111 1 × 22 + 1 × 21 + 1 × 20 8 1000 1 × 23 + 0 × 22 + 0 × 21 + 0 × 20

Example: writeBinary Write a method that takes a positive decimal number as input and writes out the equivalent number in binary. How do we convert from decimal to binary? Example: What is 8574 in binary? How about the last binary digit of 8574? It’ll be 0, just like all the other even numbers in the table

See Stutter from Monday Example: writeBinary This gives us an idea of how to break our problem down. Recall that we can split a decimal number to get the leading digits in base-10 and the final digit, given number 8574: To get the leading digits in base-2 and the final digit, we can do the same, given decimal number 8574: 857 4 n/10 n%10 See Stutter from Monday “The number of 10s in 8574” 4287 n/2 n%2 “The number of 2s in 8574”

Example: writeBinary So, what’s the base case? public static void writeBinary(int n) { }

Example: writeBinary So, what’s the base case? public static void writeBinary(int n) { if ( n < 2 ) { System.out.print(n); } else { ... } } We know what to do with a single binary digit, 0 or 1 9

Example: writeBinary What’s the recursive case? public static void writeBinary(int n) { if ( n < 2 ) { System.out.print(n); } else { ... System.out.print(n%2); } } If we have a bigger number, we can still print out its last binary digit

Example: writeBinary What’s the recursive case? public static void writeBinary(int n) { if ( n < 2 ) { System.out.print(n); } else { writeBinary(n/2); System.out.print(n%2); } } And we can recurse to print out the remaining part of the number

Another Example: sum public static int sum(int[] list) { int sum = 0; Write a method sum that takes an array of integers as a parameter and returns the sum of the numbers in the array. public static int sum(int[] list) { int sum = 0; for (int i = 0; i < list.length; i++) { sum += list[i]; } return sum; Iterative version

Example: sum Write a method sum that takes an array of integers as a parameter and returns the sum of the numbers in the array using recursion. public static int sum(int[] list) { } Base Case?

Example: sum Write a method sum that takes an array of integers as a parameter and returns the sum of the numbers in the array using recursion. public static int sum(int[] list) { if (list.length == 0) return 0; else { ... } Base Case Break problem into smaller pieces Make progress towards base case with each recursive call

Example: sum public static int sum(int[] list) { if (list.length == 0) return 0; else { ... } Break problem into smaller pieces, make progress: sum(entire list) = list[0] + sum(list starting at 1)

Example: sum When do we stop? Break problem into smaller pieces, make progress: sum(entire list) = list[0] + sum(list starting at 1) sum(list starting at 1) = list[1] + sum(list starting at 2) sum(list starting at 2) = list[2] + sum(list starting at 3) sum(list starting at 3) = list[3] + sum(list starting at 4) sum(list starting at 4) = list[4] + sum(list starting at 5) ..... When do we stop?

Example: sum Break problem into smaller pieces, make progress: sum(entire list) = list[0] + sum(list starting at 1) sum(list starting at 1) = list[1] + sum(list starting at 2) sum(list starting at 2) = list[2] + sum(list starting at 3) sum(list starting at 3) = list[3] + sum(list starting at 4) sum(list starting at 4) = list[4] + sum(list starting at 5) ..... sum(list starting at list.length-1) = list[list.length-1] + sum(list starting at list.length) sum(list starting at list.length) = 0

Example: sum Current version: public static int sum(int[] list) { if (list.length == 0) return 0; else { ... }

Example: sum Orig version: public static int sum(int[] list) { if (list.length == 0) return 0; else { ... } New version: public static int sum(int[] list, int index) {

Example: sum public static int sum(int[] list, int index) { if (index == list.length) return 0; else return list[index] + sum(list, index + 1); }

Example: sum // returns the sum of the numbers in the given array public int sum(int[] list) { return sum(list, 0); } // computes the sum of the list starting at the given index private static int sum(int[] list, int index) { if (index == list.length) return 0; else return list[index] + sum(list, index + 1);

Aside: for each loop There’s another way to look at any structure that is Iterable for (int i = 0; i < <structure>.size(); i++) { <statements> } for (<type> <name> : <structure>) { <statements> } Warning: in a for each loop, you cannot remove values see which index you’re at If you need to do that, stick with a for loop! for loop for each loop 22

for loop vs. for each loop ArrayList<Integer> list1 = new ArrayList<Integer>(); list1.add(42); list1.add(7); list1.add(-10); for (int i = 0; i < list1.size(); i++) { System.out.println(list1.get(i)); } for (int n : list1) { System.out.println(n); } for loop for each loop 23

Recursion Example: crawler Now we want to make a crawler method that will print out files and directories Java provides us with a File object http://java.sun.com/javase/6/docs/api/java/io/File.html Given the file or directory we want, we can print its name public static void print(File f) { System.out.println(f.getName()); } We also want to print the contents of a directory, though

Example: crawler We can get an array of the files in the directory and print their names: public static void print(File f) { System.out.println(f.getName()); for (File subF : f.listFiles()) { System.out.println(“ “+subF.getName()); } }

Example: crawler We can get an array of the files in the directory and print their names: public static void print(File f) { System.out.println(f.getName()); for (File subF : f.listFiles()) { System.out.println(“ “+subF.getName()); } } But this only works if f is a directory, otherwise it throws a NullPointerException 26

Example: crawler So we check to make sure f is a directory first: public static void print(File f) { System.out.println(f.getName()); if ( f.isDirectory() ) { for (File subF : f.listFiles()) { System.out.println(" “+subF.getName()); } } }

Example: crawler So we check to make sure f is a directory first: public static void print(File f) { System.out.println(f.getName()); if ( f.isDirectory() ) { for (File subF : f.listFiles()) { System.out.println(" “+subF.getName()); } } } But this still only works for one level of directories 28

Example: crawler So we check to make sure f is a directory first: public static void print(File f) { System.out.println(f.getName()); if ( f.isDirectory() ) { for (File subF : f.listFiles()) { System.out.println(" “+subF.getName()); if ( subF.isDirectory() ) { for (File subSubF : subF.listFiles() ) { ... } } } } } 29

Example: crawler So we check to make sure f is a directory first: public static void print(File f) { System.out.println(f.getName()); if ( f.isDirectory() ) { for (File subF : f.listFiles()) { System.out.println(" “+subF.getName()); if ( subF.isDirectory() ) { for (File subSubF : subF.listFiles() ) { ... } } } } } Redundant! And it still only works for one more level of directories

Example: crawler If only we had a method that would print the files in a directory...but we do! public static void print(File f) { System.out.println(f.getName()); if ( f.isDirectory() ) { for (File subF : f.listFiles()) { print(subF); } } } We probably want to add indentation, as well

Example: crawler So we add a String parameter to show how much each file name should be indented public static void print(File f, String indent) { System.out.println(indent + f.getName()); if ( f.isDirectory() ) { for (File subF : f.listFiles()) { print(subF, indent + " "); } } } We don’t want our client to need to pass a String, though

Example: crawler Instead, we make a public method for the client and hide the extra parameter by making our other method private: public static void print(File f) { print(f, ""); } private static void print(File f, String indent) { System.out.println(indent + f.getName()); if ( f.isDirectory() ) { for (File subF : f.listFiles()) { print(subF, indent + " "); } } } Using a public/private pair is common in recursion when we want to work with extra parameters

Example: Sierpinski Chapter 12 in the book discusses the Sierpinski triangle, a fractal (recursive image):

Extra Example: pow Now we want to recursively take x to the y power We’ll only deal with ints, so x and y must be ints This also means that y must be positive so that the return value is an int 35

Example: pow What’s the base case? // returns x to the y power // pre: y >= 0 public static int pow(int x, int y) { if ( y == 0 ) { return 1; } else { ... } } If y is 0, we automatically know that the power is 1! 36

Example: pow What’s the recursive case? // returns x to the y power // pre: y >= 0 public static int pow(int x, int y) { if ( y == 0 ) { return 1; } else { return x * pow(x,y-1); } } Otherwise, we can break it down into two smaller problems: xy = x1 × xy-1 37

Example: pow Taking care of negative inputs... // returns x to the y power // if y < 0, throws IllegalArgumentException public static int pow(int x, int y) { if ( y < 0 ) { throw new IllegalArgumentException(); } else if ( y == 0 ) { return 1; } else { return x * pow(x,y-1); } } 38

Example: pow But is this the best way? If I asked you to compute 232, you wouldn’t hit multiply on your calculator 32 times (hopefully!) We can also note that xy = (x2)(y/2) Example: 34 = 92 = 81 This only works for even values of y because of integer division 39

Example: pow Putting in our new idea... public static int pow2(int x, int y) { if ( y < 0 ) { throw new IllegalArgumentException(); } else if ( y == 0 ) { return 1; } else if ( y % 2 == 0 ) { return pow2(x*x, y/2); } else { return x * pow2(x,y-1); } } 40