Algorithms and OOD (CSC 207 2013F) : EBoards
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] [FAQ] [IRC] [Teaching & Learning]
Current: [Assignment] [EBoard] [Lab] [Outline] [Partners] [Reading]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Partners] [Readings]
Reference: [Java 7 API] [Java Code Conventions]
Related Courses: [CSC 152 2006S (Rebelsky)] [CSC 207 2013S (Walker)] [CSC 207 2011S (Weinman)]
Misc: [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] [Issue Tracker (Course)] [Issue Tracker (Textbook)]
Overview
The Fibonacci function:
Code?
public static int fib(int n) {
if ((n == 0) || (n == 1)) {
return 1;
} else {
return fib(n-1) + fib(n-2);
} // else
} // fib(int)
What are the problems with this solution?
How inefficient?
$ java Fib 5
fib(5) = 8
took 15 calls.
$ java Fib 8
fib(8) = 34
took 67 calls.
$ java Fib 9
fib(9) = 55
took 109 calls.
$ java Fib 20
fib(20) = 10946
took 21891 calls.
Problem: Lots of repeated work
fib(16) = fib(15) + fib(14)
= fib(14) + fib(13) + fib(14)
= fib(13) + fib(12) + fib(13) + fib(14)
Solution 1: Change the formula
fib(n) = 2*fib(n-2) + fib(n-3)
fib(16) = 2*fib(14) + fib(13)
= 2*(2*fib(12) + fib(11)) + fib(13)
= 2*(2*fib(12) + fib(11)) + 2*fib(11) + fib(10)
Whoops! Still likely to be slow.
Solution 2: Remember our old results
// FIB[n] is -1 if we haven't computed it yet, and something else if we
// have computed it.
private static int[] FIB[?]= { 1, 1, -1, -1, -1 .... }
public static int fib(int n) {
if (FIB[n] != -1) {
return FIB[n];
} else
FIB[n] = fib(n-1) + fib(n-2);
return FIB[n];
}
} // fib(int)
Hand waving argument: "This is now O(n)"
Solution 3: Why do we like tail recursion? Because we avoid the stack. So, let's do it by hand: Write it iteratively from left to right.
public static int fib(int n) {
int values[] = new int[n+1];
values[0] = 1;
values[1] = 1;
for (i = 2; i <= n; i++) {
values[i] = values[i-1] + values[i-2];
}
return values[n];
} // fib(n)
Solution 4: Drop the array
public static int fib(int n) {
int prev = 1;
int current = 1;
int next;
for (i = 2; i <= n; i++) {
next = prev+current;
prev = current;
current = next;
}
return current;
} // fib(n)
Code
public static int smallest(n) {
if (n == 0)
return 0;
else {
return 1 + "the min of smallest[n-value], for all values"
}
A better solution:
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] [FAQ] [IRC] [Teaching & Learning]
Current: [Assignment] [EBoard] [Lab] [Outline] [Partners] [Reading]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Partners] [Readings]
Reference: [Java 7 API] [Java Code Conventions]
Related Courses: [CSC 152 2006S (Rebelsky)] [CSC 207 2013S (Walker)] [CSC 207 2011S (Weinman)]
Misc: [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] [Issue Tracker (Course)] [Issue Tracker (Textbook)]
Copyright (c) 2013 Samuel A. Rebelsky.
This work is licensed under a Creative Commons Attribution 3.0 Unported License. To view a copy of this
license, visit http://creativecommons.org/licenses/by/3.0/
or send a letter to Creative Commons, 543 Howard Street, 5th Floor,
San Francisco, California, 94105, USA.