Algorithms and OOD (CSC 207 2014S) : Assignments
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] - [FAQ] [Teaching & Learning] [Grading] [Rubric] - [Calendar]
Current: [Assignment] [EBoard] [Lab] [Outline] [Reading]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Partners] [Readings]
Reference: [Java 7 API] [Java Code Conventions] [GNU Code Conventions]
Related Courses: [CSC 152 2006S (Rebelsky)] [CSC 207 2013F (Rebelsky)] [CSC 207 2013S (Walker)] [CSC 207 2011S (Weinman)]
Misc: [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] [Issue Tracker (Course)] [Issue Tracker (Textbook)]
This assignment is currently in draft form.
Due: 10:30 p.m., Wednesday, 5 March 2014
Summary: In this assignment, you will develop and analyze a variety of small programs.
Purposes: The focus of this assignment is on building your skills in designing, constructing, and testing algorithms along with loop invariants.
Collaboration: You may work alone or in a group of size two, three, or four.
Submitting:
Please put all of your work in a GitHub repository named
csc207-hw5
. Email the address of that repository
to grader-207@cs.grinnell.edu.
Please use a subject of “CSC207 2014S Assignment 5
(Optional: Your Name)”.
Warning: So that this assignment is a learning experience for everyone, we may spend class time publicly critiquing your work.
Create a new Eclipse project for this assignment. You can name the project whatever you like, provided it's not in bad taste.
In class, we've looked at a few recurrence relations that model the running time of algorithms and informally found their “closed form” (non-recursive) solution. Using similar techniques, find the closed form of the following recurrence relations.
The Dutch National Flag problem is a statement of an approach to dividing
a collection of values into three categories. Given an array of values,
vals
, and a mechanism for classifying the values as
“red” (small, belonging on the left), “white”
(medium, belonging in the middle), or “large”
(large, belonging on the right), rearrange the values so that the
red values come first, then the white values, and then the blue values.
Of course, in order to classify values, we need a classifier. Here's a useful interface.
/** * Objects that classify other objects. Useful for DNF. */ public interface Classifier<T> { /** * Classify val into one of three categories, which we call * "red", "white", and "blue" for convenience. If val is red, * returns a negative number. If val is white, returns zero. * If val is blue, returns a positive number. */ public int classify(T val); } // interface Classifier
Since dealing with generics can be difficult, we'll focus on the subproblem of rearranging arrays of strings. Ideally, we can think of the classifier like this.
/** * Objects that classify strings. Useful for DNF. */ public interface StringClassifier implements Classifier<String> { } // interface StringClassifier
But that's probably a little too sophisticated. So you can use the following definition of the interface.
/** * Objects that classify strings. Useful for DNF. */ public interface StringClassifier { /** * Classify val into one of three categories, which we call * "red", "white", and "blue" for convenience. If val is red, * returns a negative number. If val is white, returns zero. * If val is blue, returns a positive number. */ public int classify(String val); } // interface StringClassifier
Implement the following method.
/** * Rearrange vals so that red values precede white values and white values * precede blue values. * * @post * Exist P and Q, 0 <= P <= Q <= vals.length, s.t. * For all i, 0 <= i < P, classifier.classify(vals[i]) < 0 * For all i, P <= w < Q, classifier.classify(vals[i]) == 0 * For all i, Q <= i < vals.length, classifier.classify(vals[i]) > 0 * Values have neither been added to nor removed from vals; the new * vals is a permutation of the original. */ public void dnf(String[] vals, StringClassifier classifier) { // STUB } // dnf(String[], StringClassifier)
You may recall that we've identified a useful invariant for this problem. You should use this invariant, or a similar one.
+---------+---------+---------+---------+ | red | white | unknown | blue | +---------+---------+---------+---------+ | | | | | 0 r i b length
Here's a simple classifier.
/** * Classify strings as red (fewer than 5 characters), white (5 * characters), or blue (more than 5 characters). */ public class SimpleStringSizeClassifier implements StringClassifier { public int classify(String val) { return val.length() - 5; } // classify } // class SimpleStringClassifier
Here's another classifier. This one identifies strings based on their first character.
/** * Classify strings as red (starts with a lowercase letter), white * (starts with an uppercase letter), or blue (starts with anything * else, or is empty). */ public class ClassifyStringsByFirstCharacter implements StringClassifier { public int classify(String val) { // Empty strings don't start with uppercase or lowercase letters, // and are therefore blue. if (val.length() == 0) return 1; // Strings that start with a lowercase letter are red. else if (Character.isLowerCase(val.charAt(0))) return -1; // Strings that start with an uppercase letter are white. else if (Character.isUpperCase(val.charAt(0))) return 0; // Everything else is blue else return 1; } // classify(String) } // ClassifyStringsByFirstCharacter
Skip Lists are a data structure that is useful for cases in which you have a collection of values, want to be able to expand and shrink the collection, and want to be able to find values in the collection. You can learn more about skip lists from the handout.
Implement the following class.
/** * Skip lists of strings, stored alphabetically. */ public class SkipListOfStrings implements SetOfStrings { . . . } // class SkipListOfStrings
As the declaration suggests, your class should implement a simple set interface. Here is that interface.
/** * Simple sets of strings. */ public interface SetOfStrings { /** * Determine if the set contains a particular string. */ public boolean contains(String str); /** * Add an element to the set. * * @post contains(str) */ public void add(String str); /** * Remove an element from the set. * * @post !contains(str) */ public void remove(String str); } // interface SetOfStrings
You may find it useful to write loop invariants for the three methods, but you are not required to do so.
As you may recall, we can write an efficient (well, O(log_{2}n)) exponentiation algorithm by relying on the following rules.
Using invariants to help you design the algorithm, write an iterative O(log_{2}n)) exponentiation algorithm by using those rules.
/** * Compute x^n. * * @pre n >= 1. */ public double expt(double x, int n) { } // expt(double, int)
Hint: You may find it useful to keep track of two intermediate values, one of which only takes on values of x^{2k} and one of which holds the product of any other x's you need in the result.
a. Implement the following procedure, using a divide-and-conquer strategy.
/** * Search for val in values, return the index of an instance of val. * * @param val * An integer we're searching for * @param values * A sorted array of integers * @result * index, an integer * @throws Exception * If there is no i s.t. values[i] == val * @pre * values is sorted in increasing order. That is, values[i] < * values[i+1] for all reasonable i. * @post * values[index] == val */ public static int binarySearch (int i, int[] vals) throws Exception { return 0; // STUB } // binarySearch
b. Evidence suggests that (i) many programmers have difficulty implementing binary search correctly and (ii) many programmers do only casual testing of their binary search algorithm. But it's really easy to write a relatively comprehensive test suit for binary search. (The test suite is based on one by Jon Bentley.)
For each s from 1 to 32
Create an array of size s, containing the values 0, 2, 4, ... 2*(s-1)
For all i from 0 to s-1, inclusive
// Make sure that value 2*i is in position i
assert(binarySearch(2*i, array) == i)
// Make sure that odd values are not in the array
assertException(binarySearch(2*i+1, array))
assertException(-1, array)
Implement this test. Then repair any bugs you find in your implementation of binary search.
This assignment grew from exercises in class and some discussions with students.
The test for binary search is based on one from a Programming Pearl by John Bentley.
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] - [FAQ] [Teaching & Learning] [Grading] [Rubric] - [Calendar]
Current: [Assignment] [EBoard] [Lab] [Outline] [Reading]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Partners] [Readings]
Reference: [Java 7 API] [Java Code Conventions] [GNU Code Conventions]
Related Courses: [CSC 152 2006S (Rebelsky)] [CSC 207 2013F (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-14 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.