Computer Science 245: Data Structures and Algorithms


For this project, you will first create a dictionary data structure that can be used to spell-check documents. Next, you will use that dictionary to create a boggle solver.

Dictionary

The first part of this assignmet is to create the following methods for a dictionary class: For a full description of the functions you need to write, see the following Dictionary documentation You will also need to write some helper methods to implement the above methods. More on that later in this document

If you only needed to write th constructor, add, and check, then the best data structure to use would be a hash table. (We will discuss hash tables, and how they work, a bit later in the semester.) However, getting checkPrefix or suggest to work correctly using a hash table would be quite difficult. Binary search may be a little better (since we can relatively easily find words that are close together), but operations on binary search trees take time O(lg n) if you're lucky -- and can be as bad as O(n) if you're not lucky. If keys are entered in sorted order (as the likely would be for a dictionary), then you will get the worst-case performance for a binary search tree.
Instead of a hash table or a binary search tree, you will use a trie, which is s 26-ary tree, where each node has child for each leter of the alphabet, and a valid bit. To check of a word is stored in a tree, start with the root. Follow the pointer associated with the first letter in the word (if this pointer is null, the word is not in the dictionary). From that node, follow the pointer associated with the second letter of the word (again, if the pointer is null, the word is not in the dictionary). Continue until you either reach a null pointer (in which case the word is not in the dictionary), or you get to the end of the word. If you get to the end of the word, check the valid bit to see if the word in the dictionary. For example, consider the following:
Example Trie
This tree stores the words a, art, as, ask, car, cat, do, dog
This dictionary structure has three main advangages:

To see more examples of a trie in action, take a look at the Trie Visualization.

Your dictionary class will need to be named Dictionary, in the file Dictionary.java, and will need to implement the methods described in the Dictionary Documentation

Dictionary Implementation Details

Recursion

Recursion is your friend for implementing these dictionary methods. You will need to write recursive helper methods that take as one input parameter a tree, and your required methods should call these helper methods passing in the root of the tree - just like we did for binary search trees. So your add method will likely look like the following:
void add(String word)
{
    root = add(word, root)
}

Of course, you will also need to write a private version of add that takes two paramters ....

Finding a word

Consider finding a word in a tree. The word "ask" is in the following tree:
Example Tree
If and only if the work "sk" is in the following tree:
Example Tree2
What is the base case? What word is really easy to find? (If you said "A word with a single letter", what word is even easier to find?) When is that very simple word in the tree?

Finding a Prefix

Once uyou have check, checkPrefix is easy -- you have one fewer check to make.

Adding a word

Adding a word to the dictionary is is much like finding a word -- you should still recursively go down the tree until you get to the end of the word. There are two differences, however. First, when finding a word, you check to see if the valid bit is set when the end of the word is reached -- but when adding a word, you set the valid bit when the end of the word is reached. Second, when checking a word, if you come to a null pointer, you can stop looking, since the word is not in the dictionary. If you come to a null pointer when adding, however, you need to create a new node and link it into the tree.

Removing a word

There are two steps for removing a word from the dictionary. First, you need to set the valid bit at the end of the word to false. This step will remove the word from the dictionary. Next, you need to remove any branches of the tree that have no valid bits set to true. Specifically, if you set the valid bit of a leaf to false, you need to remove that leaf from the tree. If removing the leaf causes another node to becode a leaf, and that leaf has its valid bit set to false, you need to remove that leaf -- and so on, until either a valid bit is true, or you don't create a leaf. Once again, recursion is your friend here.

Hint: If you are having trouble with delete, you can get partial credit by only setting the valid bit to false, and not pruning branches with no valid bits set to true.

Suggest

The easiest way to implement suggest is to return an entry in the dictionary with the same prefix as the word that was passed in -- traverse the tree as you would for a check, and if you reach a null pointer (or you run out of word, and the current node does not have its valid bit set), then seach down any path until you find a valid bit set to true, and return that word.

Printing the dictionary

To print out your dictionary, you will want to write a function print that takes two parameters: the tree to print, and the word built up so far. When you first call the print function, you would pass in the root of the tree and an empty string (""). We'll talk about this a bit more in class when the assignment is discussed.

Indexing Child Array

The easiest way to have a child for each letter of the alphabet is to have each tree node store an array of 26 pointers: index 0 represents the 'a' child, index 1 represents the 'b' child, and so on. We will thus need to convert from a letter betwen 'a' and 'z' to a number between 0 and 25. If we cast a character to an integer, we will get the ASCII code for the character. To get this number in the range 0..25, we just need to subtract the ASCII code for 'a', as follows:
char ch = 'e';
int index = (int) ch - (int) 'a'; 

Boggle

Using a dictionary as a spellchecker is nice enough, but we'd like to do something a little more fun. Boggle is a word game, played on a 4 x 4 grid of letters. Players make works by connecting adjacent letters. To create a word, start at one cube, and then work through a chain of letters to form a word that meets the following conditions:

For instance, in the following board layout:

xx

The word "PEACE" can be made as follows:

Board

Note that the word "PLACE" is not legal, since after the "L" you would need to jump over the "H" to get to the "A". The same die cannot be resued in the same word (but can be resused again in a different word).
Longer words give more points -- 3 letter words are worth 1 point, 4-letter words are worth 2 points, and so on. The object is to find as many words as possible to get the highest possible score

Computer Boggle

Because the computer has a complete dictionary and you do not, we've tried to make the game a little more interesting by letting you find as many words as you can and then turning the computer loose to find the rest. If you're thorough, you can beat the computer because it is not allowed to count words you've already found. Most games, however, still end up as a rout, with the computer completley trouncing the human.

Provided Files

In order to make this project a reasonable size, we have given you most of the code for Boggle. You only need to write two different methods (plus any helper methods required to get your methods to work correctly): We have provided a class Board.java that includes stubs for these two methods -- you need to fill in these stubs (and add any additional helper functions that are required for your methods to work correctly)

Support Files

Grading

Your project will be graded on the following criteria:

Collaboration

It is OK for you to discuss solutions to this program with your classmates. However, no collaboration should ever involve looking at one of your classmate's source programs! It is usually extremely easy to determine that someone has copied a program, even when the individual doing the copying has changed identifier names and comments.

Project Submission

Submit all the files required to run Boggle to your subversion directory, under the folder cs245/project2/:
 
https://www.cs.usfca.edu/svn/username/cs245/project2/