CS 161 Assignment #8

Due Saturday, April 13th at 11:59pm
(Not accepted after 4/15)

Introduction

For your penultimate assignment you'll use your knowledge of Binary Search to create an efficient implementation of a set. A set in computer science is like the mathematical definition of a set: It's a collection of data values, without duplicates, but one in which there's no notion of an index. You can add items to the set, or check to see if a value is in the set, but you can't ask (for example) to see the third item in the set. Sets get used in lots of algorithms in computer science, and we'll use this very same set implementation as part of our final project this semester so do a good job!

Teams

On this assignment, you can work individually as in the past or in teams of two. If you choose to work in a team, please make sure that only one member of the team submits the assignment, and also make sure that the names of both team members are at the top of your code.

Discussion

One way to implement a set would be via an unordered list of integer values. When the user asks us to add a new value, we could just add it to the end of the list (assuming it wasn't already in the set). That makes adding simple, but makes looking for values (or removing them) harder. For example, if the user wanted to know if the set contained a 17, we would have to work our way through the list, checking each item to see if it was a 17. And, in fact, even when adding items, we would need to do a linear search like that to see if the new value was already in the set.

If we kept the items in the list ordered instead, we could use binary search when checking for items, which would be much faster. That means we'd need to be careful when adding new items, to ensure that the list stayed ordered, but binary search can help us here too! As described below, binary search can get us to the position at which a new item needs to be inserted to keep the list ordered. Your job will be to fill in the missing methods to create a set for holding integer values.

The Assignment

Download the IntSet project as a starting point. There's not much code in the class yet, but the project contains the hidden files necessary to be able to submit the assignment when you're done so make sure you start with it. The class contains the following field:
    private ArrayList<Integer> values; 
When the user asks us to add a value to a set, we will store it in this ArrayList, but we'll be careful to make sure the list stays ordered when adding new items so that we can use binary search on it when necessary. The steps below will guide you through implementing the methods required for the set class.
  1. As mentioned above, we can use binary search when looking for items in our set, but it will also come in handy when adding items. Since binary search will be used in several other methods, let's start by writing a find method that can be used as a "helper" elsewhere: It should take an int as its input and use binary search to narrow the search down to a single location in the values ArrayList, but instead of checking whether the "key" really is at that location it should return the index of that final "box".

    You'll need to adapt our binary search code from class so that it works on ArrayLists, but the required changes should be pretty minimal. Also, while you might want to leave this method public until you've finished testing your code, it should be private in the final version you submit. This is not a method we want the user to access — it's only there to assist in the implementation of other methods within the class. Also, for full credit, make sure you use your find method in the rest of your code any time you need to search the ArrayList. (Do not use methods like contains or indexOf on the values list elsewhere in your class.)

  2. Define a toString method for the IntSet class that returns a string containing all of the integer values stored in the set. It's fine if this string looks exactly like the results of ArrayList's toString method. (That was a hint.)
  3. Define a size method that returns the number of integers in the IntSet. (If this is more than one line of code, you made it harder than it needed to be.)
  4. Define a method called contains that takes an integer as its input and returns true if the item is in the set (false if it's not). Since you already implemented binary search in the find method, there's not much to do here: Call find to see where the item would be located if it were in the ArrayList, then check that one position to see if it's there.
  5. Define a void method called add that takes an integer as its input, and adds it to the set if it's not already present. This requires a bit of care, since we need to keep the list ordered. Here's a start at a to-do list: Note: Don't use the sorting code we developed in class as part of your solution — it's much more efficient to use find as described above to add the value in the right spot since the list is already in order before the call to add.
  6. Define a void method called merge that takes an IntSet as its input, and adds all of the items from the input set to the current set. (Hint: You just need to call the add method from the previous step a bunch of times — once for each item in the input set.)
  7. Define a void method called remove that takes an integer as its input and removes that value from the set if it was present. The find method is your friend here as well:
  8. Define a void method called subtract that takes an IntSet as its input, and removes all items in that set from our current set. Just like merge, this just means calling remove once for each item in the input set.

Sample Interactions

Some sample interactions in the codepad with an IntSet are shown below. Note that my find method was left public for these interactions so I could test it, but I later changed it to private as required. Also, note that unless find works, none of the other methods will work since they all depend on the list staying in order!

IntSet s = new IntSet();
s.add(20);
s.add(10);
s.add(30);
s.add(5);
s.add(30);
s.toString()
  "[5, 10, 20, 30]"   (String)
s.size()
  4   (int)
s.find(5)
  0   (int)
s.find(4)
  0   (int)
s.find(25)
  2   (int)
s.find(35)
  3   (int)
s.contains(5)
  true   (boolean)
s.contains(30)
  true   (boolean)
s.contains(15)
  false   (boolean)
s.remove(15);
s.remove(20);
s.remove(5);
s.toString()
  "[10, 30]"   (String)

Style Guide

Before you submit your assignment, go through the checklist below and make sure your code conforms to the style guide.

Grading

This assignment will be graded out of a total of 100 points:

Submitting

Before submitting, make sure your code conforms to the style guide above, and that you've thoroughly tested all of your methods. When you're convinced it's ready to go, submit the project via BlueJ just like you have in the past.


Brad Richards, 2024