{[ promptMessage ]}

Bookmark it

{[ promptMessage ]}

Module 4

Module 4 - Module 4 Algorithms that remember accumulative...

This preview shows pages 1–3. Sign up to view the full content.

Module 4 Algorithms that remember: accumulative recursion Because it’s best not to compute the same thing over and over CS 116: Introduction to Computer Science 2 Daniel G. Brown/Troy Vasiga, University of Waterloo 4.1 Purpose of Module 4 Accumulative recursion: the idea behind it Several examples of accumulative recursion Designing and debugging accumulatively recursive code. Readings: HtDP 30, 31 4.2 1 The idea of accumulative recursion Accumulative recursion Accumulative recursion is another kind of recursion that keeps information from one recursive call to the next. Example 1 . The factorial of n , written n !, is the product of all numbers from 1 up to n . We can compute this very easily in Scheme. ;; factorial: num num ;; compute the product of the numbers from 1 to n ;; Examples: ;; (factorial 3) 6 ;; (factorial 1) 1 ( define ( factorial n ) ( cond [(= n 1) 1] [ else ( * n ( factorial ( sub1 n )))])) 4.3 The reason for accumulative recursion What happens when we compute ( factorial 6) ? ( factorial 6) ( * 6 ( factorial 5)) ( * 6 ( * 5 ( factorial 4))) ( * 6 ( * 5 ( * 4 ( factorial 3)))) ( * 6 ( * 5 ( * 4 ( * 3 ( factorial 2))))) ( * 6 ( * 5 ( * 4 ( * 3 ( * 2 ( factorial 1)))))) ( * 6 ( * 5 ( * 4 ( * 3 ( * 2 1))))) ( * 6 ( * 5 ( * 4 ( * 3 2)))) 1

This preview has intentionally blurred sections. Sign up to view the full version.

View Full Document
... 720 Note: the formula gets more and more complicated. This doesn’t matter for us if we think of computing in terms of re-writing formulas. But computers exist as physical devices, and carrying all of these recursive calls takes up memory on the physical device. We might run out of space very quickly. It’s also probably not how human beings would do it. 4.4 An alternative approach We could keep the intermediate formulas much smaller, by doing one multiplication in each recursive call, and keeping the product of all the numbers we’ve seen so far as a function argument. ;; factorial2: num num ;; (purpose and examples as in factorial) ( define ( factorial2 n ) ;; running-product: num num num ;; compute the product of n0! * prod-so-far ( local [( define ( running-product n0 prod-so-far ) ( cond [(= n0 1) prod-so-far ] [ else ( running-product ( sub1 n0 ) ( * prod-so-far n0 ))]))] ( running-product n 1))) Here, each successive call to running-product has two arguments: n0 , the number that counts down to 1 , and prod-so-far , the product of all of the numbers from n down to n0 4.5 An example trace of this function Here’s what happens when we compute ( factorial2 6) : ( factorial2 6) ( running-product 6 1) ( running-product 5 ( * 1 6 )) ( running-product 5 6) ( running-product 4 ( * 6 5)) ( running-product 4 30) ( running-product 3 ( * 30 4)) ( running-product 3 120) ( running-product 2 ( * 120 3)) ( running-product 2 360) ( running-product 1 ( * 360 2)) ( running-product 1 720) 720 4.6 Differences between the two implementations There are two big differences: We keep track of the product of the numbers we’ve seen so far in a second parameter, prod-so-far .
This is the end of the preview. Sign up to access the rest of the document.

{[ snackBarMessage ]}