Applications Lab
The goal of this lab is to apply some of the techniques and structures we’ve studied this semester. You should read the problem descriptions, determine appropriate collection types, and implement efficient solutions. You should work in groups on this lab.
DO NOT RE-INVENT THE WHEEL! None of these problems require custom data structures; they can all be implemented efficiently using existing data structures from the Java Collections Framework. These include the following (among others):
Interface | Hash Table | Resizable Array | Balanced Tree | Linked List | Hash Table + Linked List |
---|---|---|---|---|---|
Set |
HashSet | TreeSet | LinkedHashSet | ||
List |
ArrayList | LinkedList | |||
Deque |
ArrayDeque | LinkedList | |||
Map |
HashMap | TreeMap | LinkedHashMap |
Duplicate Tracker
Begin by downloading the following files:
Complete the methods of the DuplicateTracker
class so that all
operations are as efficient as possible. The purpose of this class is
to process a sequence of user IDs such that duplicate IDs are
identified and may be efficiently retrieved as a sorted List
. You
should assume that both the “add” and the “get” methods may be called
arbitrarily many times and in any order: efficiency matters for both.
Here is a code snippet that illustrates the desired functionality:
tracker.addID(5);
tracker.addID(2);
tracker.addID(1);
tracker.addID(2);
tracker.addID(5);
tracker.addID(5);
System.out.println(tracker.getDuplicates()); // Prints "[2, 5]"
tracker.addID(1);
System.out.println(tracker.getDuplicates()); // Prints "[1, 2, 5]"
You can test your implementation by executing the JUnit tests. These will run some tests for correctness as well as timing tests. Your goal is to pass all correctness tests with an overall execution time that is as small as possible.
Job Sequencer
Begin by downloading the following files:
Complete the methods of the JobSequencer
class so that all operations
are as efficient as possible. The purpose of this class is to process
jobs of different types in the order that they are added to the
system. Because there are a limited number of job handlers and they
are specialized for a particular job type, you must make sure that the
“nextJob” methods only return jobs of the requested type. You must also
ensure that jobs of a particular type are processed in the order in
which they arrived. You should assume that both the “addJob” and the
“nextJob” methods may be called arbitrarily many times and in any order:
efficiency matters for both.
Here is a code snippet that illustrates the desired functionality:
JobSequencer sequencer = new JobSequencer();
sequencer.addJob("A", 101);
sequencer.addJob("B", 105);
sequencer.addJob("A", 93);
sequencer.addJob("B", 202);
System.out.println(sequencer.nextJob("A")); // Prints "101"
System.out.println(sequencer.nextJob("B")); // Prints "105"
System.out.println(sequencer.nextJob("B")); // Prints "202"
System.out.println(sequencer.nextJob("A")); // Prints "93"
Event Sequencer
Begin by downloading the following files:
Complete the methods of the EventSequencer
class so that all
operations are as efficient as possible. The purpose of this class is
to store events that are tagged with an integer time stamp and then to
return those events in strict chronological order: once an event with
a particular time stamp has been retrieved, it should not be possible
to retrieve an event with an equal or earlier time stamp, even if this
means that some events are discarded. You should assume that both the
“add” and the “get” methods may be called arbitrarily many times and
in any order: efficiency matters for both.
EventSequencer sequencer = new EventSequencer();
sequencer.addEvent(0, "A"); // Event "A" at time 0.
sequencer.addEvent(4, "C");
sequencer.addEvent(1, "B");
System.out.println(sequencer.nextEvent()); // Prints "A"
System.out.println(sequencer.nextEvent()); // Prints "B"
sequencer.addEvent(1, "e"); // Event "A" at time 0.
sequencer.addEvent(3, "f");
sequencer.addEvent(5, "g");
System.out.println(sequencer.nextEvent()); // Prints "f"
System.out.println(sequencer.nextEvent()); // Prints "C"
System.out.println(sequencer.nextEvent()); // Prints "g"