University of California, Berkeley
EECS Department - Computer Science Division
CS3L OaW Lecture 6 : Recursion and Patterns
Thanks to Oliver Grillmeyer and Brendan Ferguson for
many of the ideas for these notes
Review : Recursion!
An algorithmic technique where a function, in order
to accomplish a task, calls itself with some part of the task.
- Recursive solutions involve two major parts:
- Base case(s), in which the problem is simple enough
to be solved directly,
- Recursive case(s). A recursive case has three components:
- Divide the problem into one or more simpler or smaller
parts of the problems,
- Invoke the function (recursively) on each part, and
- Combine the solutions of the parts into a solution
for the problem.
- Depending on the problem, any of these may be trivial or
complex.
Announcements
- Quest results
... use the subtotal as your real sanity check
- Other admin questions?
Common Confusions
- Let's do a quick check-in ... are you feeling like you're getting recursion?
Recursion and Patterns
Overview
- One of the things we'll notice is that there are recurring
patterns when we write our recursive programs
- We'll see the following main patterns for recursive programs:
Recursive patterns we'll see on sentences
- Mapping (e.g., every, which you'll see soon)
- Takes a sentence and does something to every element in the
sentence and returns a sentence of the same size
- e.g., square-all, square all numbers in a sentence
- Finding (like member?)
- Finding the first element of a sentence that satisfies test,
and return either that element or the rest of the sentence starting
with that element, #f otherwise.
- e.g., member-even, return the rest of the sentence
starting with the first even number, #f ottherwise.
- Counting (like count)
- Counting the number of elements that satisfy a test
- e.g., count-evens, return the number of even numbers
in a sentence
- e.g., my-count, which returns the number of words
in the sentence
- Filtering (like keep, which you'll see soon)
- Takes a sentence and for each element, decides to either
keep or discard it.
- e.g., remove-evens, remove all the even numbers
in a sentence
- e.g., keep-ones, which returns a sentence of the
ones in the sentence
- Testing (like all?, which you'll see soon)
- Predicate which checks something about every or any
element of the sentence, returns whether it's true or not
- e.g., all-evens? which returns #t if all numbers
are even
- Combining (like accumulate, which you'll see soon)
- Combine the elements of the sentence in some way
- e.g., get-min, which gets the minimum element
- e.g., sentence-sum, which returns the sum of the
elements in a numeric sentence
Mapping Example : square-all
;; square-all
;;
;; INPUTS : A sentence, s
;; REQUIRES : The sentence contain only numbers
;; SIDE-EFFECTS : None
;; RETURNS : A sentence of the same size as the input, but with
;; : all elements squared.
;; EXAMPLE : (square-all '()) ==> ()
;; : (square-all '(1 2 3 4)) ==> (1 4 9 16)
: (define (square x) (* x x))
square
(define (square-all s)
==>
==>
==>
: (square-all '())
==>
: (square-all '(1 2 3 4))
==>
Finding Example : member-even
;; member-even
;;
;; INPUTS : A sentence, s
;; REQUIRES : The sentence contain only numbers
;; SIDE-EFFECTS : None
;; RETURNS : The rest of the sentence starting with the first even #
;; : and #f if none exists (just like member would have)
;; EXAMPLE : (member-even '()) ==> #f
;; : (member-even '(1 2 3 4)) ==> (2 3 4)
;; : (member-even '(1 3 5 7)) ==> #f
(define (member-even s)
==>
==>
==>
: (member-even '())
==>
: (member-even '(1 2 3 4))
==>
: (member-even '(1 3 5 7))
==>
Counting Example : count-evens
;; count-evens
;;
;; INPUTS : A sentence, s
;; REQUIRES : The sentence contain only numbers
;; SIDE-EFFECTS : None
;; RETURNS : The number of even numbers in the sentence
;; EXAMPLE : (count-evens '()) ==> 0
;; : (count-evens '(1 2 3 4)) ==> 2
;; : (count-evens '(2 4 6 8)) ==> 4
;; : (count-evens '(1 3 5 7)) ==> 0
(define (count-evens s)
==>
==>
==>
==>
: (count-evens '())
==>
: (count-evens '(1 2 3 4))
==>
: (count-evens '(2 4 6 8))
==>
: (count-evens '(1 3 5 7))
==>
Filtering Example : remove-evens
;; remove-evens
;;
;; INPUTS : A sentence, s
;; REQUIRES : The sentence contain only numbers
;; SIDE-EFFECTS : None
;; RETURNS : The sentence with the even numbers removed
;; EXAMPLE : (remove-evens '()) ==> ()
;; : (remove-evens '(1 2 3 4)) ==> (1 3)
;; : (remove-evens '(2 4 6 8)) ==> ()
;; : (remove-evens '(1 3 5 7)) ==> (1 3 5 7)
(define (remove-evens s)
==>
==>
==>
==>
==>
: (remove-evens '())
==>
: (remove-evens '(1 2 3 4))
==>
: (remove-evens '(2 4 6 8))
==>
: (remove-evens '(1 3 5 7))
==>
Testing Example : all-evens?
;; all-evens?
;;
;; INPUTS : A sentence, s
;; REQUIRES : The sentence contain only numbers
;; SIDE-EFFECTS : None
;; RETURNS : #t if the entire sentence is even, #f otherwise
;; : This can also be thought of as (not (any-odds? s))
;; EXAMPLE : (all-evens? '()) ==> #t
;; : (all-evens? '(1 2 3 4)) ==> #f
;; : (all-evens? '(2 4 6 8)) ==> #t
;; : (all-evens? '(1 3 5 7)) ==> #f
(define (all-evens? s)
==>
==>
==>
==>
: (all-evens? '())
==>
: (all-evens? '(1 2 4 8))
==>
: (all-evens? '(2 4 6 8))
==>
: (all-evens? '(1 3 5 7))
==>
Combining Example : get-min
;; get-min
;;
;; INPUTS : A sentence, s
;; REQUIRES : The sentence contain only numbers
;; : The sentence have length at least one
;; : (because the min of nothing is undefined)
;; SIDE-EFFECTS : None
;; RETURNS : The minimum number in the sentence
;; EXAMPLE : (get-min '(795)) ==> 795
;; : (get-min '(3 1 4 1)) ==> 1
(define (get-min s)
==>
==>
==>
: (get-min '(795))
==>
: (get-min '(3 1 4 1))
==>
: (get-min '()) ;; This violates our requirements
==>
Summary
- We saw lots of examples of recursion, and hopefully some
patterns we highlighted started to sink in.
In Lab this week you'll see...
- Roman Numerals programs
- Recursive programs with two arguments, and accumulating recursions
In Life this week you'll see...
- An interesting debate between our VP candidates on thursday...
- Cal (3-1) take on Arizona St on Saturday