Previous Lecture | Lecture 14 | Next Lecture |
Lecture 14, Tue 03/13
Recursion
Hand traced examples in lecture
# CS 8, 3-13-18
''' Recursion
- When a function contains a call to itself.
- We're mostly familiar with writing code in an iterative
fashion (i.e. one statement after the other).
- Many programming languages exist where it's based
purely on recursion.
- Recursive problems are useful when the result is
dependent on the result of its subparts.
PROPERTIES OF RECURSION
- One or more base cases that provide the "stopping"
condition
- One or more recursive valls, where the parameters are
"closer" to the base case than the function input.
'''
# Simple example: Factorial
# n! = n * (n - 1) * (n - 2) * ... * 1
# n! = n * (n - 1)!
# 0! = 1
def factorial(n):
if n == 0: # base case
return 1
return n * factorial(n-1)
assert factorial(0) == 1
assert factorial(1) == 1
assert factorial(2) == 2
assert factorial(3) == 6
assert factorial(4) == 24
# What happens if we forget the base case?
def factorial2(n):
print(n)
return n * factorial2(n-1)
#factorial2(4)
# Infinite recursion! No stopping condition means the
# caller never returns the value.
# Program crashes - STACK OVERFLOW
# What happens if we never progress to the base case?
def factorial3(n):
if n == 0:
return 1
#print(n)
return n * factorial3(n+1)
#factorial3(4)
# Infinite recursion, the stopping condition is never
# reached.
# Example: Check if a string is a palindrome
def isPalindrome(s):
''' A string that is the same forward and backward
is considered a palindrome
Ex: "racecar", "hannah", "civic"'''
if len(s) == 0 or len(s) == 1: # base case
return True
if s[0] != s[-1]:
return False
else:
return isPalindrome(s[1:len(s)-1]) # continue checking
assert isPalindrome("racecar") == True
assert isPalindrome("civic") == True
assert isPalindrome("CS8") == False
# Example: Filter through and return a collection
def removeEvenNumbers(L):
''' For a list of numbers, L, returns a list where
all even numbers are removed '''
if len(L) == 0: # base case
return []
if L[0] % 2 == 0:
return removeEvenNumbers(L[1:]) # discard item
else:
return [L[0]] + removeEvenNumbers(L[1:]) # keep item
assert removeEvenNumbers([1,2,3,4]) == [1,3]
assert removeEvenNumbers([1,1,1,1]) == [1,1,1,1]
assert removeEvenNumbers([2,4,6]) == []
# Example: Fibonacci
# A fibonacci sequence, the nth number in the sequence is the
# sum of the previous two. For example:
# f(n) = f(n-1) + f(n-2)
# f(0) = 0, f(1) = 1, f(2) = 1, f(3) = 2, f(4) = 3, f(5)=5, ...
def fibonacci(n):
if n == 1: # base cases
return 1
if n == 0:
return 0
return fibonacci(n-1) + fibonacci(n-2)
assert fibonacci(0) == 0
assert fibonacci(1) == 1
assert fibonacci(2) == 1
assert fibonacci(3) == 2
assert fibonacci(4) == 3
assert fibonacci(5) == 5
assert fibonacci(6) == 8
# Example: reverse a string
def reverseString(s):
if s == "": # base case
return ""
return reverseString(s[1:]) + s[0]
assert reverseString("CS8") == "8SC"
assert reverseString("") == ""
assert reverseString("a") == "a"
assert reverseString("hooray!") == "!yarooh"