|
cs205: engineering software? |
(none) 25 June 2008 |
|
Problem Set 2 Procedural Abstraction and Using Abstract Datatypes |
Out: 30 August Due: Friday, 8 September (beginning of class) |
Collaboration Policy - Read Carefully: For this problem set, you may work alone or with one other student in the class. If you work with another student, you should both participate fully in all parts of the assignments and turn in one assignment with both of your names on it. Either way, feel free to ask other students for help and offer help to other students.
Purpose
For the next question, consider these two specifications for the sort procedure:
A. From the Java 2 Platform API documentation (java.util.Arrays):
public static void sort(int[ ] a) Sorts the specified array of ints into ascending numerical order. The sorting algorithm is a tuned quicksort, adapted from Jon L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November 1993). This algorithm offers n*log(n) performance on many data sets that cause other quicksorts to degrade to quadratic performance. |
B. From the textbook (p.46):
public static void sort(int[ ] a) MODIFIES: a |
public static int [] histogram (int [] a)
// unspecified
{
int maxval = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] > maxval) {
maxval = a[i];
}
}
int histo [] = new int [maxval + 1];
for (int i = 0; i < a.length; i++) {
histo[a[i]]++;
}
return histo;
}
For example,
int [] test = { 1, 2, 3, 4, 6, 4, 3, 3, 0 } ;
int [] hist = histogram (test);
the value of hist will be [1, 1, 1, 3, 2, 0, 1].
The input file lists a task, followed by a number (which could represent the time required to complete the task), followed by a list of tasks upon which this dask depends. Lines that start with a # are treated as commments.
For example,
# Based on Figure 13.9 (p. 323) of textbook
Engine 30 { Comm.getDocs TitleTable Doc Query WordTable }
Comm.getDocs 50 { }
TitleTable 60 { Doc }
Doc 15 { }
Query 30 { WordTable }
WordTable 20 { Doc }
describes the dependency graph shown in Figure 13.9 of the textbook.
The first task listed in the file (Engine in the example) is the main task. The output of your program should be a schedule of tasks that can be used to complete the main task, and the total time needed to complete it. For the example there are many possible valid schedules; one valid output would be:
Schedule: [Comm.getDocs, Doc, TitleTable, WordTable, Query, Engine] Completion time: 205Note that every task in the list is preceeded by all tasks upon which it depends.
We have provided you with several abstract datatypes that you should find helpful in building your implementation. Their specifications are at the end of this document. Note that we provide only the specifications and class file implementations, not the source code. Your code should work with any implementations of these datatypes that satisfy the provided specifications.
You should implement your program by creating a new TaskScheduler class (in the ps2 package) with a main method.
public class DirectedGraph<T> OVERVIEW: A DirectedGraph is a directed graphwhere V is a set of nodes (of type T), and E is a set of edges. Each edge is a pair (v1, v2), representing an edge from v1 to v2 in G. public DirectedGraph() EFFECTS: Creates a new, empty DirectedGraph: < {}, {} > public void addNode(T s) throws DuplicateException MODIFIES: this EFFECTS: If s is the name of a node in this, throws DuplicateNodeException. Otherwise, adds s to the nodes in this, with no adjacent nodes: Gpost = < Vpre U { s }, Epre > public void addEdge(T s, T t) throws NoNodeException, DuplicateException MODIFIES: this EFFECTS: If s and t are not nodes in this, throws NoNodeException. If there is already an edge between s and t, throws DuplicateEdgeException. Otherwise, adds an edge between s and t to this: Gpost = < Vpre, Epre U > public Set<T> getAdjacent(T s) throws NoNodeException EFFECTS: If s is not a node in this, throws NoNodeException. Otherwise, returns a set containing the nodes adjacent to s That is, returns the set of nodes { e | <s, e> is in E }
public class Set<T> implements Iterable<T>, Collection<T> {
OVERVIEW: A Set is a mutable, unbounded set of objects of type T.
A typical Set is {x_1, ..., x_n }.
public Set()
EFFECTS: Initializes this to an empty set: { }.
public Set(Set<T> s)
EFFECTS: Initializes this to a set containing the same elements
as the set s (a shallow copy).
public boolean add(T el)
MODIFIES: this
EFFECTS: Adds el to the elements of this:
thispost = thispre U { el }
Returns true iff el was not an element of
thispre.
public void union(Set<T> t)
MODIFIES: this
EFFECTS: this_post = this_pre U t
public Iterator<T> iterator()
REQUIRES: this must not be modified while the
iterator is in use.
EFFECTS: Returns an iterator that yields each element of
this.
public T choose()
REQUIRES: this has at least one element
EFFECTS: Returns an element of this.
public boolean contains(Object el)
EFFECTS: Returns true iff el is an element of this.
public int size()
EFFECTS: Returns the number of elements in this.
public boolean isEmpty()
EFFECTS: Returns true iff this has no elements.
public boolean remove(Object el)
MODIFIES: this
EFFECTS: Removes el from this:
this_post = this_pre - { el }
Returns true iff el is in thispre
public class Task
OVERVIEW: A typical Task is < name, time, dependencies > where
name is the name of this task, time is the time it takes
to complete it (in minutes), and dependencies is a set
of tasks that must be completed before this task can
be done.
public Task (String p_name, int p_time, String [] p_dependencies)
EFFECTS: Initializes this to the task .
public String getName ()
EFFECTS: Returns the name of this.
public int getTime ()
EFFECTS: Returns the time of this.
public String [] getDependencies ()
EFFECTS: Returns the dependencies of this.
public String toFullString ()
EFFECTS: Returns a detailed string description of this.
public String toString ()
EFFECTS: Returns a short string description of this (just the name).
The most useful java.util.Vector methods are specified below:
public class Vector<T> {
OVERVIEW: A Vector is a mutable, unbouded, ordered collection of
objects of type T. A typical Vector is [x_0, ..., x_n].
public Vector()
EFFECTS: Initializes this to an empty vector, [].
public boolean add(T el)
MODIFIES: this
EFFECTS: Appends el to the end of this. Returns true.
If this_pre = [x_0, ..., x_n], this_post = [x_0, ..., x_n, el].
public void add(int index, T el)
REQUIRES: 0 <= index <= size
MODIFIES: this
EFFECTS: Inserts el at location index in this.
All elements before index are preseved unchanged, and
all elements after index are advanced one position.
public boolean remove(Object el)
MODIFIES: this
EFFECTS: Removes the first occurance of an element whose value is
equal to el (as matched using equals) from
this. Returns true there is a matching occurance; otherwise,
returns false and leaves this unchanged.
public boolean contains(Object el)
EFFECTS: Returns true iff an object with the same value as
el is an element of the Vector as determined by equals.
The Vector class also implements the Iterator
interface, so you can iterate through the elements of a Vector (in
order) using:
Vector v = new Vector ();
...
for (String el : v) {
... // Do something on each element
}
public class Scanner {
OVERVIEW: A Scanner provides an abstract interface to textual data.
A typical Scanner is < c1, c2, c3, ..., cn >
^
where ci is the ith character in the text, and the cursor (^)
points to the next character to process. A Scanner may be
open or closed; a closed Scanner has no cursor.
public Scanner(File source) throws FileNotFoundException
EFFECTS: If source is not a readable file, throws FileNotFoundException.
Otherwise, initializes this to a scanner containing the characters in
the file source with the cursor pointing to the first character.
public Scanner(String source)
EFFECTS: Initializes this to a scanner containing the characters in
the source string with the cursor pointing to the first character.
public boolean hasNextLine()
REQUIRES: this is an open scanner
EFFECTS: Returns true iff there is another line in the text for
this scanner.
public String nextLine()
REQUIRES: this is an open scanner and the cursor is not at the end
of the input
MODIFIES: this
EFFECTS: Returns the next line in the text (from the current cursor
to either the end of the text or a line separator
character). The line separator is not included in the
return value. The text of the scanner is unchanged.
The cursor advances to the position immediately
following the line separator if one was reached, or
to the end of the text.
public boolean hasNextInt()
REQUIRES: this is an open scanner
EFFECTS: Returns true if the characters starting from the current
cursor can be interpreted as a valid integer.
public int nextInt()
REQUIRES: this is an open scanner and the cursor points to a
sequence of characters that can be interpreted as an integer.
MODIFIES: this
EFFECTS: Return the value of the next integer in the file (using
as many characters as possible to form a valid integer), and
advances the cursor to the position immediately following
the input used.
public boolean hasNext()
REQUIRES: this is an open scanner
EFFECTS: Returns true if this scanner has another token.
public String next()
REQUIRES: this is an open scanner with at least one more token.
MODIFIES: this
EFFECTS: Returns the next token in this scanner, and advances the
cursor to point to the position immediately following the
returned token. The next token is as many non-whitespace characters
as can be read until the next whitespace character.