This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Application Lab

Introduction

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
Queue, Deque ArrayDeque LinkedList
Map HashMap TreeMap LinkedHashMap

Notably missing from the table is the PriorityQueue class.

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"

Triage

Begin by downloading the following files:

Complete the methods in TriageTracker so that all operations are as efficient as possible. The purpose of this class is to prioritize patients as they seek health care. Each patient is entered into the system along with an integer priority value that quantifies the urgency of their medical condition. The nextPatient method should always remove and return the patient with the highest priority. In event of tied priorities, patients should be processed in the order they were added. The removePatient method makes it possible to remove a patient from the collection even if he or she has not been served.

    TriageTracker triage = new TriageTracker();
    
    triage.addPatient("01-A", 10); // Patient "01-A" has priority 10.
    triage.addPatient("02-A", 10);
    triage.addPatient("03-A", 1);
    triage.addPatient("04-A", 1);
    triage.addPatient("05-A", 10);
    triage.addPatient("06-A", 5000);
    
    triage.removePatient("02-A"); // Patient "02-A" got tired of waiting.
    
    System.out.println(triage.nextPatient()); // "06-A" (Highest priority)
    System.out.println(triage.nextPatient()); // "01-A" (First 10 priority)
    System.out.println(triage.nextPatient()); // "05-A" ("02-A" was removed!)
    System.out.println(triage.nextPatient()); // "03-A"
    System.out.println(triage.nextPatient()); // "04-A"

Neighbors

Complete the methods in NeighborCounter so that all operations are as efficient as possible. The purpose of this class is to maintain a collection of two-dimensional points and to determine how many points are within a particular distance from a query point. Duplicate points at the same location are not permitted.

    NeighborCounter nc = new NeighborCounter();
    
    // Add four points arranged in a square pattern:
    nc.addPoint(0.0, 0.0);
    nc.addPoint(0.0, 1.0);
    nc.addPoint(1.0, 0.0);
    nc.addPoint(1.0, 1.0);

    // All four points are within 1.0 of (.5, .5)...
    System.out.println(nc.numNeighbors(.5, .5, 1.0));  // Prints 4

    // No points are within .1 of (.5, .5)...
    System.out.println(nc.numNeighbors(.5, .5, 0.1));  // Prints 0

    // Only one point, (0, 0), is within .5 of (.1, .1)...
    System.out.println(nc.numNeighbors(.1, .1, .5));   // Prints 1

Lab Submission

Submit BSTDictionary.java to Gradescope.