Some Dos and Don'ts About Homework
- Make sure that the output submitted in all assignments matches the program
that you submit.
- If you know of problems with your program, please note them!! You are much
better off telling us about them than us finding them ourselves.
- Make sure that your listing for Homeworks matches what you put in the
dropbox. It is not to hard to tell if a homework is submitted to meet
the deadline and the listing is further changed.
- Make sure to use a folder for Homeworks.
- Howework will be graded in large part on style, not just whether it works:
- Correctness - 3 pts. (Does it work? Any bugs?)
- Decomposition - 4 pts. (Good use of functions and parameters?
Parameters the right # and types?)
- Problem Structure - 4 pts. (Game state clearly defined? Right amount? Avoid special cases?)
- Testing - 4 pts. (Tests exercise all the code?)
- Style - 5 pts. (Comments and indentation? Consts? I/O correct,
descriptive, accurate?)
Recursion
Recursion is the defining and solving of a problem in terms of smaller
instances of the same problem.
Example: Sierpinsky Gasket
Fractal: 1 1 <--- 1 bit symbolizes a pixel turned on
0 1 <--- 0 bit symbolizes a pixel turned off
See sierpinskyColor.cpp Demo
Example: factorial
Recall:
n! = n * (n - 1) * (n - 2) * ... * 2 * 1
See factIterative.cpp Demo
Observe that that (n - 1) * (n - 2) * ... * 2 * 1 is just (n-1)!. So,
we can rewrite our definition of n! as
n! = 1 if n = 0 (the base case),
n! = n * (n-1)! if n >= 1 (the recursive case).
See factRecursive.cpp Demo
How it works
Each recursive call causes a fresh copy of the stack
frame for the function. An example stack of the factorial function
for n = 3 is given below:
For each call to factorial a new stack frame is pushed onto the program
stack. This occurs until our base case is met, namely when n is 0. Once
our base case is reached, we return until we reach our original function
main()
, where the return value is 6 and is the answer
to our original call of factorial(3)
.
Infinite Recursion
Infinte recursion occurs when you never hit the base case. When the base
case is never reached the computer continually pushes new stack frames onto
its stack until it runs out of memory. When this occurs you either crash
the machine or get a fault which will halt the execution of the runaway
program.
Thinking Recursively
Recursion is really based on mathematical induction.
Induction works in the following way. Suppose we want to show that
something works for all nonnegative integers.
- Prove that it works for n = 0 (or whatever the appropriate base
case is).
- Then prove that if it works for all k < n, then
it works for n too. This is the induction part.
- Therefore we can conclude that it works for all n >= 0.
For factorial:
- Base Case: n = 0
- Induction:Know how to compute (n - 1)!. Use it to compute
n!.
Another example: Fibonacci Numbers
- fib(i) = ith Fibonacci number
- fib(1) = fib(2) = 1
- fib(n) = fib(n - 1) + fib(n - 2) if n >= 3
- Base Cases: n = 1, n = 2
- Induction: Know how to compute fib(n - 1), fib(n - 2).
Use them to compute fib(n).
See fibonacci.cpp Demo
Example: Reversing a Sentence
We can reverse a sentence using recursion also.
- Set tail = all letters except the first.
- Then: reverse(sentence) = reverse(tail) followed by the first letter of the
sentence.
- Base Case:No letters. An empty sentence is its own
reverse.
- Induction:example - made ==> edam
- The tail is ade.
- We reverse ade to get eda.
- Then tack on the m to get edam.
See reverse.cpp Demo
To Index
Previous
Next