LMU ☀️ CMSI 2120
DATA STRUCTURES
HOMEWORK #6 Due: 2022-12-08

Learning Objectives

With this assignment you will demonstrate:

Readings and Videos

Please:

Be wary of online solutions

A fair amount of online code is rather poor, and when you do find good code, it may be using a very old version of Java. For this assignment, you are required to use Modern (17+) Java and implement methods recursively, so pretty much most of the online ternary search tree examples will not apply.

Don’t forget that copying code from existing sources greatly diminishes your opportunity for learning and practice. You are expected to work as hard as possible until you can progress no further, then check with me or a TA to show what you have tried—before looking at anyone else’s code.

To the extent that you do get ideas from existing code, you are expected to give attribution and modify the code to fit the required parameters for this assignment.

Instructions

Work in teams of 1 to 2 students.

Your work will be done in the same private GitHub repository hosting your previous assignments for this course. In the comments of your BrightSpace submission, place the link to your GitHub repo. If BrightSpace asks you for a file attachment, attach an image of a ternary search tree or a dank meme. Submit only one submission per team.

Structure your repository, for now, as follows:

  .
  ├── README.md
  ├── .gitignore
  ├── homework1/
  │   └── (existing files from previous assignments)
  ├── homework2/
  │   └── (existing files from previous assignments)
  ├── homework3/
  │   └── (existing files from previous assignments)
  ├── homework4/
  │   └── (existing files from previous assignments)
  └── homework5/
  │   └── (existing files from previous assignments)
  └── homework6/
      ├── README.md                (Include ALL students’ names)
      ├── WordFinder.java          (starter code on course notes)
      └── WordFinderTest.java      (given to you below)

When grading, I will clone your repository, and run the tests. As you know, since the repo is to be private, please add me as a contributor to your repo (so I can run and comment on your work). My github name is rtoal.

You will be graded on your programming style, so make sure you are set up so that your editor or IDE auto-formats your code. You should also install Sonar Lint because it is amazing. Environment set up was carried out in class earlier, so you should be good already.

Your homework submission will be the state of your repository on the branch master, at 23:59 in the America/Los Angeles time zone on the due date above.

Make sure your README has the names of all the students that have worked on the project.

The Class You Are To Write

For this assignment, you will create a Java class called WordFinder whose functionality can be determined from the supplied unit test below. Essentially, a word finder represents a collection of non-empty, non-blank words, optimized for autocompletion. The methods are:

finder.add(word)
Add the given word, trimmed, to the collection, throwing an IllegalArgumentException if the word is blank.
finder.contains(word)
Return whether the given word (which you should trim first) is in the collection.
finder.allWords()
Return the sorted list of all of the added (and previously trimmed) words.
finder.suggestions(prefix)
Return a sorted list of all words in the collection having the given prefix (which you should trim first), but if the prefix is blank, throw an IllegalArgumentException.

There are, however, some important implementation restrictions that are not covered by the tests below, but that I will manually check when grading:

The Unit Tests

Here is the unit test file:

WordFinderTest.java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.List;

public class WordFinderTest {

    WordFinder finder = new WordFinder();

    @Test
    public void testAddingEmptyWordsThrows() {
        assertThrows(IllegalArgumentException.class, () -> finder.add(""));
        assertThrows(IllegalArgumentException.class, () -> finder.add("   "));
    }

    @Test
    public void testNewFinderIsEmpty() {
        assertFalse(finder.contains("dog"));
        assertEquals(List.of(), finder.allWords());
        assertThrows(IllegalArgumentException.class, () -> finder.suggestions(""));
        assertEquals(List.of(), finder.suggestions("i"));
        assertEquals(List.of(), finder.suggestions("dog"));
    }

    @Test
    public void testSingleWordFinder() {
        finder.add("dog");
        assertTrue(finder.contains("dog"));
        assertTrue(finder.contains("  dog"));
        assertTrue(finder.contains("dog "));
        assertTrue(finder.contains("  dog   "));
        assertFalse(finder.contains("cat"));
        assertEquals(List.of("dog"), finder.allWords());
        assertEquals(List.of(), finder.suggestions("i"));
        assertThrows(IllegalArgumentException.class, () -> finder.suggestions(""));
        assertEquals(List.of("dog"), finder.suggestions("d"));
        assertEquals(List.of("dog"), finder.suggestions("do"));
        assertEquals(List.of("dog"), finder.suggestions("dog"));
        assertEquals(List.of("dog"), finder.suggestions("dog   "));
    }

    @Test
    public void testMultiwordFinder() {
        finder.add("dog");
        finder.add("role");
        finder.add("  door  ");
        finder.add("rat ");
        finder.add("dishes");
        finder.add("  roller");
        assertTrue(finder.contains("rat"));
        assertTrue(finder.contains("roller "));
        assertThrows(IllegalArgumentException.class, () -> finder.suggestions(""));
        assertEquals(List.of("dishes", "dog", "door", "rat", "role", "roller"), finder.allWords());
        assertEquals(List.of("dishes", "dog", "door"), finder.suggestions("d"));
        assertEquals(List.of("dog", "door"), finder.suggestions("do"));
        assertEquals(List.of("role", "roller"), finder.suggestions("ro"));
        assertEquals(List.of("role", "roller"), finder.suggestions("rol  "));
        assertEquals(List.of("roller"), finder.suggestions("roll"));
        assertEquals(List.of("role"), finder.suggestions("role"));
        assertEquals(List.of(), finder.suggestions("rolex"));
        assertEquals(List.of(), finder.suggestions("parsimonious"));
    }
}

Grading

As before, the following elements will all contribute to your grade:

In addition, I will be scoring code quality, which is sometimes subjective to be sure, but you deserve feedback.