CS 2 (Winter 2025) Lab 04: Anagrams

This lab focuses on using recursive backtracking and data structures to solve two versions of an enumeration problem.

Setup

As always, register for the lab using the registration tool: https://register.caltech.codes. Then, follow the same instructions as last time to clone the repository and use IntelliJ.

Goals and Outcomes

By the end of this lab, you will…

The Anagrams Problem

An anagram is a word or phrase made by rearranging the letters of another word or phrase. In this lab, we differentiate between two types of anagrams of a String \(s\):

As always, examples make this significantly more clear.

\[\begin{align} \require{extpfeil}\text{meat} &\xmapsto[\text{word}]{} \{\text{mate}, \text{meat}, \text{tame}, \text{team}\}\\ \text{meat} &\xmapsto[\text{phrase}]{} \{\text{mate}, \text{meat}, \text{tame}, \text{team}\}\\ \text{magikarp} &\xmapsto[\text{word}]{} \{\}\\ \text{magikarp} &\xmapsto[\text{phrase}]{} \{\text{karma pig}, \text{magi park}, \text{park magi}, \text{pig karma}\}\\ \text{listen} &\xmapsto[\text{word}]{} \{\text{listen}, \text{silent}, \text{tinsel}\}\\ \text{listen} &\xmapsto[\text{phrase}]{} \{\text{let sin}, \text{listen}, \text{lit sen}, \text{nil set}, \text{sen lit}, \text{sen til}, \text{set nil}, \text{silent}, \text{sin let}, \text{til sen}, \text{tinsel}\} \end{align}\]

Provided Helper Class: LetterBag

We have provided you with a simple LetterBag class which you will find helpful in your implementation.

public LetterBag(String s)

The LetterBag constructor takes in a String and creates a mapping between characters in that string and the number of times they appear in that string.

public LetterBag subtract(LetterBag other)

Takes in another LetterBag and creates a new LetterBag that represents the difference between this and other by subtracting the counts for each letter.


Note: this method returns null if there are more of any given character in other than in this.

public boolean isEmpty()

Checks if there are any letters in this LetterBag.

Solving the Phrase Anagrams Problem

One of the goals of this lab is to implement a recursive backtracking algorithm. As discussed in lecture, enumeration problems lend themselves very nicely to the recursive backtracking pattern.

public static printPhrases(String phrase, List<String> dictionary)

Prints all the phrase anagrams of phrase ignoring all non-lowercase letters.


  • You will need an accumulator like used in lecture. In this case, you will want to use a List of Strings.
  • You will need to keep track of “what letters are left to use” in a choice. (Hint: the LetterBag class could be useful here.)
  • It is very easy to get stuck on this type of problem. Please remember to use the members of course staff that are in the room. We will be especially helpful for this lab.

At this point, if printPhrases is implemented properly, all of the PhraseAnagramsTests should pass.

Solving the Word Anagrams Problem

The second goal of this lab is to see how small changes in problems can allow more clever solutions which run significantly faster. Our phrase anagram solution effectively runs over all multisets of dictionary words.

This is extremely inefficient if all we care about is printing matching words. It’s possible to find the word anagrams of a phrase in time proportional to the size of the dictionary.

This time, you should use an algorithmic pattern centered around a data structure, rather than recursive backtracking. There are ways to make this very fast, but they are not necessary to get credit for this lab.

public static printWords(String phrase, List<String> dictionary)

Prints all the word anagrams of phrase ignoring all non-lowercase letters.


This method must run in time proportional to the size of the dictionary. You may not use recursion.

At this point, if printWords is implemented properly, all of the WordAnagramsTests should pass.

Submitting Your Code for Credit

Your code will be autograded when you submit it to gitlab. You may submit to gitlab as many times as you like, and only the last submission will be counted.

Committing and Pushing to the Repository

A “commit” is version control language for a chunk of changes that mean something when grouped together. Importantly, commits will only stay locally on your machine until you push them to the gitlab server.

Checking the Results on gitlab

When you go to https://gitlab.caltech.edu, you should see your lab02 repository listed. Click on it. All the way on the right, there should be a red “X”, an orange “pause” symbol, a blue “time” symbol, or a green “check” symbol. This symbol indicates the status of the automated tests which will check the correctness of your code. Click on it. On the new page, you should see a table, and under “status”, there should be another symbol. Click on it. The new page will list the “categories” of tests for this repository. These will be some combination of “A”, “B”, “C”, and “D”. These letters indicate what grade you earned on the assessment for passing those tests. If you click on one of them, it will detail for you which sub-tests you passed and failed which might help you debug.

It is good practice to always check gitlab after submitting a project or lab in this course.