Solving Problems Recursively



Similar documents
Arrays. number: Motivation. Prof. Stewart Weiss. Software Design Lecture Notes Arrays

Chapter 5. Recursion. Data Structures and Algorithms in Java

The Tower of Hanoi. Recursion Solution. Recursive Function. Time Complexity. Recursive Thinking. Why Recursion? n! = n* (n-1)!

Pseudo code Tutorial and Exercises Teacher s Version

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?

Data Structures. Algorithm Performance and Big O Analysis

csci 210: Data Structures Recursion

Boolean Expressions, Conditions, Loops, and Enumerations. Precedence Rules (from highest to lowest priority)

What Is Recursion? Recursion. Binary search example postponed to end of lecture

Dynamic Programming. Lecture Overview Introduction

CSCI 123 INTRODUCTION TO PROGRAMMING CONCEPTS IN C++

Course: Programming II - Abstract Data Types. The ADT Stack. A stack. The ADT Stack and Recursion Slide Number 1

Module 2 Stacks and Queues: Abstract Data Types

CSE373: Data Structures and Algorithms Lecture 3: Math Review; Algorithm Analysis. Linda Shapiro Winter 2015

Functions Recursion. C++ functions. Declare/prototype. Define. Call. int myfunction (int ); int myfunction (int x){ int y = x*x; return y; }

Common Data Structures

Lecture Notes on Linear Search

Answers to Review Questions Chapter 7

CS 2412 Data Structures. Chapter 2 Stacks and recursion

16. Recursion. COMP 110 Prasun Dewan 1. Developing a Recursive Solution

What is a Loop? Pretest Loops in C++ Types of Loop Testing. Count-controlled loops. Loops can be...

Recursion and Recursive Backtracking

Curriculum Map. Discipline: Computer Science Course: C++

Appendix K Introduction to Microsoft Visual C++ 6.0

6. Control Structures

MS Visual C++ Introduction. Quick Introduction. A1 Visual C++

Introduction to Programming (in C++) Loops. Jordi Cortadella, Ricard Gavaldà, Fernando Orejas Dept. of Computer Science, UPC

Sample Questions Csci 1112 A. Bellaachia

Example. Introduction to Programming (in C++) Loops. The while statement. Write the numbers 1 N. Assume the following specification:

VISUAL GUIDE to. RX Scripting. for Roulette Xtreme - System Designer 2.0

Lab 4.4 Secret Messages: Indexing, Arrays, and Iteration

Loop Invariants and Binary Search

12-6 Write a recursive definition of a valid Java identifier (see chapter 2).

Algorithms. Margaret M. Fleck. 18 October 2010

Chapter 5 Functions. Introducing Functions

Chapter 6. Linear Programming: The Simplex Method. Introduction to the Big M Method. Section 4 Maximization and Minimization with Problem Constraints

Lecture 3. Arrays. Name of array. c[0] c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] c[9] c[10] c[11] Position number of the element within array c

1 Description of The Simpletron

Algorithm Design and Recursion

CS104: Data Structures and Object-Oriented Design (Fall 2013) October 24, 2013: Priority Queues Scribes: CS 104 Teaching Team

AP Computer Science Java Mr. Clausen Program 9A, 9B

Introduction to Data Structures

Passing 1D arrays to functions.

What Is Recursion? 5/12/10 1. CMPSC 24: Lecture 13 Recursion. Lecture Plan. Divyakant Agrawal Department of Computer Science UC Santa Barbara

Recursion. Slides. Programming in C++ Computer Science Dept Va Tech Aug., Barnette ND, McQuain WD

Introduction to Programming (in C++) Multi-dimensional vectors. Jordi Cortadella, Ricard Gavaldà, Fernando Orejas Dept. of Computer Science, UPC

Recursion. Definition: o A procedure or function that calls itself, directly or indirectly, is said to be recursive.

Programming Exercises

2x + y = 3. Since the second equation is precisely the same as the first equation, it is enough to find x and y satisfying the system

An Incomplete C++ Primer. University of Wyoming MA 5310

Data Structures using OOP C++ Lecture 1

UIL Computer Science for Dummies by Jake Warren and works from Mr. Fleming

The C++ Language. Loops. ! Recall that a loop is another of the four basic programming language structures

Lecture 3: Finding integer solutions to systems of linear equations

AP Computer Science A 2011 Free-Response Questions

The While Loop. Objectives. Textbook. WHILE Loops

14:440:127 Introduction to Computers for Engineers. Notes for Lecture 06

Class Overview. CSE 326: Data Structures. Goals. Goals. Data Structures. Goals. Introduction

9 Control Statements. 9.1 Introduction. 9.2 Objectives. 9.3 Statements

CAs and Turing Machines. The Basis for Universal Computation

Object Oriented Software Design

WESTMORELAND COUNTY PUBLIC SCHOOLS Integrated Instructional Pacing Guide and Checklist Computer Math

Create Your Own Picture Tubes

Math 55: Discrete Mathematics

Base Conversion written by Cathy Saxton

1.4 Arrays Introduction to Programming in Java: An Interdisciplinary Approach Robert Sedgewick and Kevin Wayne Copyright /6/11 12:33 PM!

6. Standard Algorithms

Regression Verification: Status Report

Matrix Multiplication

Moving from C++ to VBA

Session 7 Fractions and Decimals

COMPUTER SCIENCE 1999 (Delhi Board)

A binary search tree or BST is a binary tree that is either empty or in which the data element of each node has a key, and:

Comp151. Definitions & Declarations

Section 1.4. Difference Equations

Recursive Algorithms. Recursion. Motivating Example Factorial Recall the factorial function. { 1 if n = 1 n! = n (n 1)! if n > 1

Ready, Set, Go! Math Games for Serious Minds

AP Computer Science A 2004 Free-Response Questions

QUIZ-II QUIZ-II. Chapter 5: Control Structures II (Repetition) Objectives. Objectives (cont d.) 20/11/2015. EEE 117 Computer Programming Fall

10CS35: Data Structures Using C

Analysis of Binary Search algorithm and Selection Sort algorithm

Introduction to Matlab

COMP 356 Programming Language Structures Notes for Chapter 10 of Concepts of Programming Languages Implementing Subprograms.

C++FA 5.1 PRACTICE MID-TERM EXAM

Project 2: Bejeweled

F ahrenheit = 9 Celsius + 32

This loop prints out the numbers from 1 through 10 on separate lines. How does it work? Output:

1. What are Data Structures? Introduction to Data Structures. 2. What will we Study? CITS2200 Data Structures and Algorithms

Moving from CS 61A Scheme to CS 61B Java

K80TTQ1EP-??,VO.L,XU0H5BY,_71ZVPKOE678_X,N2Y-8HI4VS,,6Z28DDW5N7ADY013

LOBs were introduced back with DB2 V6, some 13 years ago. (V6 GA 25 June 1999) Prior to the introduction of LOBs, the max row size was 32K and the

Ch 7-1. Object-Oriented Programming and Classes

recursion here it is in C++ power function cis15 advanced programming techniques, using c++ fall 2007 lecture # VI.1

SYSTEMS OF EQUATIONS AND MATRICES WITH THE TI-89. by Joseph Collison

Unit 1 Number Sense. In this unit, students will study repeating decimals, percents, fractions, decimals, and proportions.

1) The postfix expression for the infix expression A+B*(C+D)/F+D*E is ABCD+*F/DE*++

Deposit Direct. Getting Started Guide

Transcription:

Solving Problems Recursively Recursion is an indispensable tool in a programmer s toolkit Allows many complex problems to be solved simply Elegance and understanding in code often leads to better programs: easier to modify, extend, verify (and sometimes more efficient!! See expotest.cpp) Sometimes recursion isn t appropriate, when it s bad it can be very bad---every tool requires knowledge and experience in how to use it The basic idea is to get help solving a problem from coworkers (clones) who work and act like you do Ask clone to solve a simpler but similar problem Use clone s result to put together your answer Need both concepts: call on the clone and use the result Print words entered, but backwards Can use a vector, store all the words and print in reverse order The vector is probably the best approach, but recursion works too void PrintReversed() string word; if (cin >> word) // reading succeeded? PrintReversed(); // print the rest reversed cout << word << endl; // then print the word int main() PrintReversed(); The function PrintReversed reads a word, prints the word only after the clones finish printing in reverse order Each clone has its own version of the code, its own word variable A Computer Science Tapestry 10.1 A Computer Science Tapestry 10.2 Exponentiation Computing x n means multiplying n numbers (or does it?) What s the easiest value of n to compute x n? If you want to multiply only once, what can you ask a clone? double Power(double x, int n) // post: returns x^n if (n == 0) return 1.0; return x * Power(x, n-1); What about an iterative version? Faster exponentiation How many recursive calls are made to computer 2 1024? How many multiplies on each call? Is this better? double Power(double x, int n) // post: returns x^n if (n == 0) return 1.0; double semi = Power(x, n/2); if (n % 2 == 0) return semi*semi; return x * semi * semi; What about an iterative version of this function? A Computer Science Tapestry 10.3 A Computer Science Tapestry 10.4

Recursive and Iterative log powers In the program expotest.cpp we calculate x n using log(n) multiplications (basically). We do this both iteratively and recursively using BigInt variables We saw the iterative code in Chapter 5 with doubles BigInt has overloaded operators so these values work like ints and doubles We use the CTimer class to time the difference in using these functions (ctimer.h) The recursive version is faster, sometimes much faster Using doubles we wouldn t notice a difference Artifact of algorithm? Can we fix the problem? Natural version of both in programs, optimizing tough. Back to Recursion Recursive functions have two key attributes There is a base case, sometimes called the exit case, which does not make a recursive call See print reversed, exponentiation, factorial for examples All other cases make a recursive call, with some parameter or other measure that decreases or moves towards the base case Ensure that sequence of calls eventually reaches the base case Measure can be tricky, but usually it s straightforward Example: sequential search in a vector If first element is search key, done and return Otherwise look in the rest of the vector How can we recurse on rest of vector? A Computer Science Tapestry 10.5 A Computer Science Tapestry 10.6 Classic examples of recursion Fibonacci: Don t do this recursively For some reason, computer science uses these examples: Factorial: we can use a loop or recursion (see facttest.cpp), is this an issue? Fibonacci numbers: 1, 1, 2, 3, 5, 8, 13, 21, F(n) = F(n-1) + F(n-2), why isn t this enough? What s needed? Classic example of bad recursion, to compute F(6), the sixth Fibonacci number, we must compute F(5) and F(4). What do we do to compute F(5)? Why is this a problem? Towers of Hanoi N disks on one of three pegs, transfer all disks to another peg, never put a disk on a smaller one, only on larger Every solution takes forever when N, number of disks, is large long RecFib(int n) // precondition: 0 <= n // postcondition: returns the n-th Fibonacci number if (0 == n 1 == n) return 1; else return RecFib(n-1) + RecFib(n-2); How many clones/calls to compute F(5)? 4 3 2 2 1 1 0 1 1 0 5 2 How many calls of F(1)? How many total calls? See recfib2.cpp for caching code 3 1 0 A Computer Science Tapestry 10.7 A Computer Science Tapestry 10.8

Towers of Hanoi The origins of the problem/puzzle may be in the far east Move n disks from one peg to another in a set of three void Move(int from, int to, int aux, int numdisks) // pre: numdisks on peg # from, // move to peg # to // post: disks moved from peg 'from // to peg 'to' via 'aux' if (numdisks == 1) cout << "move " << from << " to " << to << endl; else Move (from,aux,to, numdisks - 1); Move (from,to,aux, 1); Move (aux,to,from, numdisks - 1); Peg#1 #2 #3 A Computer Science Tapestry 10.9 What s better: recursion/iteration? There s no single answer, many factors contribute Ease of developing code assuming other factors ok Efficiency (runtime or space) can matter, but don t worry about efficiency unless you know you have to In some examples, like Fibonacci numbers, recursive solution does extra work, we d like to avoid the extra work Iterative solution is efficient The recursive inefficiency of extra work can be fixed if we remember intermediate solutions: static variables Static function variable: maintain value over all function calls Local variables constructed each time function called A Computer Science Tapestry 10.10 Fixing recursive Fibonacci: recfib2.cpp long RecFib(int n) // precondition: 0 <= n <= 30 // postcondition: returns the n-th Fibonacci number static tvector<int> storage(31,0); if (0 == n 1 == n) return 1; else if (storage[n]!= 0) return storage[n]; else storage[n] = RecFib(n-1) + RecFib(n-2); return storage[n]; What does storage do? Why initialize to all zeros? Static variables initialized first time function called Maintain values over calls, not reset or re-initialized Thinking recursively Problem: find the largest element in a vector Iteratively: loop, remember largest seen so far Recursive: find largest in [1..n), then compare to 0 th element double Max(const tvector<double>& a) // pre: a contains a.size() elements, 0 < a.size() // post: return maximal element of a int k; double max = a[0]; for(k=0; k < a.size(); k++) if (max < a[k]) max = a[k]; return max; In a recursive version what is base case, what is measure of problem size that decreases (towards base case)? A Computer Science Tapestry 10.11 A Computer Science Tapestry 10.12

Recursive Max double RecMax(const tvector<double>& a, int first) // pre: a contains a.size() elements, 0 < a.size() // first < a.size() // post: return maximal element a[first..size()-1] if (first == a.size()-1) // last element, done return a[first]; double maxafter = RecMax(a,first+1); if (maxafter < a[first]) return a[first]; else return maxafter; What is base case (conceptually)? We can use RecMax to implement Max as follows return RecMax(a,0); Recognizing recursion: void Change(tvector<int>& a, int first, int last) // post: a is changed if (first < last) int temp = a[first]; // swap a[first], a[last] a[first] = a[last]; a[last] = temp; Change(a, first+1, last-1); // original call (why?): Change(a, 0, a.size()-1); What is base case? (no recursive calls) What happens before recursive call made? How is recursive call closer to the base case? A Computer Science Tapestry 10.13 A Computer Science Tapestry 10.14 More recursion recognition int Value(const tvector<int>& a, int index) // pre:?? // post: a value is returned if (index < a.size()) return a[index] + Value(a,index+1); return 0; // original call: cout << Value(a,0) << endl; What is base case, what value is returned? How is progress towards base case realized? How is recursive value used to return a value? What if a is vector of doubles, does anything change? One more recognition void Something(int n, int& rev) // post: rev has some value based on n if (n!= 0) rev = (rev*10) + (n % 10); Something(n/10, rev); int Number(int n) int value = 0; Something(n,value); return value; What is returned by Number(13)? Number(1234)? This is a tail recursive function, last statement recursive Can turn tail recursive functions into loops very easily A Computer Science Tapestry 10.15 A Computer Science Tapestry 10.16

Non-recursive version int Number(int n) // post: return reverse of n, e.g., 4231 for n==1234 int rev = 0; // rev is reverse of n's digits so far while (n!= 0) rev = (rev * 10) + n % 10; n /= 10; Why did recursive version need the helper function? Where does initialization happen in recursion? How is helper function related to idea above? Is one of these easier to understand? What about developing rather than recognizing? Two-Dimensional vectors/matrices Many problems lead to grids, boards, matrices Represent images as rectangular grid of pixels What about 3-D images? What's in a pixel? Represent boards/grids as 2-D collection tvector<string> ttt(3,"xxx"); ttt[0] = "X "; ttt[1] = " X "; ttt[2] = " "; ttt[2][2] = 'X'; // we have a winner! Why are there two indices used with tttt? A Computer Science Tapestry 10.17 A Computer Science Tapestry 10.18 More on grids, vectors, matrices tvector<double> line(30,0.0); tvector<tvector<double> > grid(20,line); for(int k=0; k < 20; k++) grid[k][5] = 4.0; 0 0 0 0 0 4 0 0 0 0 0 0 0 4 Twenty rows 0 0 0 0 0 4 How is # rows specified? Columns? Thirty columns How do we set row with index 8 to have value 2.0? for(int k=0; k < 30; k++) grid[8][k] = 2.0; The class tmatrix and 2-D arrays Represents grid, similar to tvector Two-dimensional, specify both dimensions Rather than using size(), use numrows(), numcols() A vector<vector< > > is similar, and standard Can also specify grid using standard array-notation int x[] = 1,2,3,4,5; // like tvector of 5 elements int grid[20][30]; // like matrix, but fixed in size If the grid is global, initiliazed to all 0's, otherwise need for(int j=0; j < 20; j++) for(int k=0; k < 30; k++) grid[j][k] = 0; A Computer Science Tapestry 10.19 A Computer Science Tapestry 10.20

Blob Counting: Recursion at Work Blob counting is similar to what s called Flood Fill, the method used to fill in an outline with a color (use the paintcan in many drawing programs to fill in) Possible to do this iteratively, but hard to get right Simple recursive solution Suppose a slide is viewed under a microscope Count images on the slide, or blobs in a gel, or Erase noise and make the blobs more visible To write the program we ll use a class CharBitMap which represents images using characters The program blobs.cpp and class Blobs are essential too Counting blobs, the first slide prompt> blobs enter row col size 10 50 # pixels on: between 1 and 500: 200 +--------------------------------------------------+ * * * * * * *** * **** * * * * *** ** ** * * * * * * * * *** * * *** * * * * * * * * ** * ** ** * ** * * * *** * * * * ***** *** * * ** ** * * * * * * * ** * *** * *** * * * *** * ** * * * * * ** * * ** * * * * *** ** * **** * * ** **** * *** * * ** ** * * * ** **** ** * * ** * +--------------------------------------------------+ How many blobs are there? Blobs are connected horizontally and vertically, suppose a minimum of 10 cells in a blob What if blob size changes? A Computer Science Tapestry 10.21 A Computer Science Tapestry 10.22 Identifying Larger Blobs blob size (0 to exit) between 0 and 50: 10...1......111......1......11......111...2......1...2......111...33...2......1...3...222.22......11..3333...222......33.3333... # blobs = 3 The class Blobs makes a copy of the CharBitMap and then counts blobs in the copy, by erasing noisy data (essentially) In identifying blobs, too-small blobs are counted, then uncounted by erasing them Identifying smaller blobs blob size (0 to exit) between 0 and 50: 5...1...2......1.1...222......111...333.2...4......33..22...444...5......33333.222...6...44...55......2...6...444...555......222...77...6...4......8...2...7...666.66....8888...22..7777...666... 88..8...77.7777... # blobs = 8 What might be a problem if there are more than nine blobs? Issues in looking at code: how do language features get in the way of understanding the code? How can we track blobs, e.g., find the largest blob? A Computer Science Tapestry 10.23 A Computer Science Tapestry 10.24

Issues that arise in studying code What does static mean, values defined in Blobs? Class-wide values rather than stored once per object All Blob variables would share PIXEL_OFF, unlike myblobcount which is different in every object When is static useful? What is the class tmatrix? Two-dimensional vector, use a[0][1] instead of a[0] First index is the row, second index is the column We ll study these concepts in more depth, a minimal understanding is needed to work on blobs.cpp Recursive helper functions Client programs use Blobs::FindBlobs to find blobs of a given size in a CharBitMap object This is a recursive function, private data is often needed/used in recursive member function parameters Use a helper function, not accessible to client code, use recursion to implement member function To find a blob, look at every pixel, if a pixel is part of a blob, identify the entire blob by sending out recursive clones/scouts Each clone reports back the number of pixels it counts Each clone colors the blob with an identifying mark The mark is used to avoid duplicate (unending) work A Computer Science Tapestry 10.25 A Computer Science Tapestry 10.26 Conceptual Details of BlobFill Once a blob pixel is found, four recursive clones are sent out looking horizontally and vertically, reporting pixel count How are pixel counts processed by clone-sender? What if all the clones ultimately report a blob that s small? In checking horizontal/vertical neighbors what happens if there aren t four neighbors? Is this a potential problem? Who checks for valid pixel coordinates, or pixel color? Two options: don t make the call, don t process the call Non-recursive member function takes care of looking for blobsign, then filling/counting/unfilling blobs How is unfill/uncount managed? Saving blobs In current version of Blobs::FindBlobs the blobs are counted What changes if we want to store the blobs that are found? How can clients access the found blobs? What is a blob, does it have state? Behavior? What happens when a new minimal blob size is specified? Why are the Blob class declaration, member function implementations, and main function in one file? Advantages in using? blobs.h, blobs.cpp, doblobs.cpp? How does Makefile or IDE take care of managing multiple file projects/programs? A Computer Science Tapestry 10.27 A Computer Science Tapestry 10.28