Motivation
Sets are container classes like bags and lists. Like bags, but unlike
lists, sets are unordered. Unlike for bags and lists, duplication of
elements is not allowed for sets.
As an example, imagine you are a disc jockey for a local college radio station (I said imagine). Part of your job is to take requests for songs. The radio station has a policy of playing no repeats (at least on the same day), but sometimes the requests are redundant. If we store the requests in a set, then repetition can be avoided, and we won't necessarily play the songs in the request order (which is good since it can prevent musical clashes, such as hearing Metallica right after Prince).
Sets are extremely useful in implementing algorithms related to other fundamental data structures, as we will see later in the semester when we look at graphs. To get a flavor for the kind of roles sets will play, suppose that you want to know how many cities you can fly to via commercial airlines from Madison making no more than one stop en route. We might consider first the collection of all cities that can be reached from Madison nonstop. We could add these to a list. Then we might consider all the cities that can be reached from those cities and then add them to our list. But there will likely be lots of duplication on the list. (For example, we can fly from Madison to Chicago to New York, from Madison to Detroit to New York, and from Madison to Minneapolis to New York.) If we use sets, we avoid this problem.
We might want to then consider each of these cities in turn as candidates for a trip. But we don't necessarily want to consider them in any particular order. Lists impose an order even when we don't want one. Sets do not.
Of course, we could avoid the second problem by just ignoring the order of the list and we could avoid the first problem by checking before adding an element to see if it was already on our list. This makes a nice segue into what this assignment is about: implementing a set class using a list class.
(For more info about sets, read below.)
The Assignment
This assignment concerns the implementation of a template class Set using a
template class List.
The assignment is intended to:
Requirements
In the true spirt of container classes, we don't want our sets (or our
lists) to be constrained to be of just one type, so we use template classes.
You have three (rather extensive) requirements for this assignment:
Grading
The program will be graded on an 100 point scale, weighted as follows:
Files
There are five files you will need to do the assignment, found in
~cs367-3/Assignments/One/Files:
cp ~cs367-3/Assignments/One/Files/* ~foo/cs367
You should expect to modify list.h , list.C list.h , and set.h . You should plan on crating a file set.C for the implementation of the Set template class member functions. You may modify main.C and Makefile, but be advised that the compilation grade is dependent upon your other files working properly with the given main.C and Makefile. (You may want to make a different main and Makefile for testing out the list application - you could base such a program on the test program used for the bag assignment, or on a test program used to for the list classes discussed in class, such as the one here.)
Sets
Sets are notated as elements, comma separated between curly braces, as in:
{3,1,2}, {"hello","goodbye"}, and {{3.14,2.71},{}}. We consider Sets to be
homogeneous - for a given set, all its elements are of the same type.
Basic operations on sets include:
{x,y} is a set containing x and y. Order does not matter in sets, so {x,y} is the same as {y,x}.
Two sets are equal if and only if all the elements in the first set are present in second set and all the elements in the second set are present in the first.
If S and T are equiavlent sets, then after the operations:
S.add(x); S.add(y); T.add(y); T.add(x);S and T are still equal.
Duplication does not occur in sets. If S and T are equal, then after the operations:
S.add(x); T.add(x); T.add(x); T.add(x); T.add(x);S and T are still equal.
Binary operations are often defined on sets, such as:
Additions to List
In class we talked about classes for lists of one specific type (either int or
String). The List template class is a generalization of those classes, with
a few changes. In particular, three additional private members have been
added:
Previously, the capacity of a list, despite its linked-list representation was a fixed constant (CAPACITY) for all list objects - a holdover from our initial array implementation. Now, each list can have a distinct capacity. This is important because we may want to have a smaller limit on lists that hold larger items. A list's capacity is set at construction time. The default constructor, List(size_t cap = DEFAULT_CAPACITY), takes an optional size_t argument, cap. The capacity is set to be cap if it is specified, DEFAULT_CAPACITY (a new public member constant is specified), if it is not. In the documentation for Sets, no capacity argument is given for the default Set constructor. This is done for simplicity - it is expected that the sets will have capacity equal to the DEFAULT_CAPACITY of lists.
Previously, for the linked-list representation of lists, the number of elements on the list was determined by walking from the head of the list until NULL was reached. Now, the length() function simply returns count. Of course, count must be maintained properly in the insert functions, remove, and the constructors. Think about the complexity of former implementation of length() versus the new implementation. Given that the length() function is needed fairly frequently (for example, in the equality operator), it should be clear why it is beneficial to use the extra bytes of memory to store the count in a member variable.
Previously, we used only a pointer to the first item on the list (*head). In order to find the last item on the list we iterated as in:
for(p=head; p->next!=NULL; p=p->next);*tail is a pointer to the last item, so this loop is no longer needed, *tail can be used directly. As with count, this simplifies some functions that need the last item to be found, but requires some additional machinery to insert functions, remove, and the constructors. Also as with count, this is a tradeoff of a small amount of memory (enough to store a pointer) for a more efficient implementation.
Related Reading
C++ topics relevant to this assignment covered in the texts:
Submitting
What we need once you are done: your versions of list.h, list.C, set.h, and
set.C. You can submit additional files if necessary, but bear in mind that
the compile grade hinges upon our ability to compile your file with the
original
main.C and
Makefile. Copy the necessary files to the directory
~cs367-3/Submissions/One/<login> where <login> is your login
name. For example if your login name is foo, then from the directory where your
modified bag.C file is located, type:
cp bag.C ~cs367-3/Submissions/One/fooThis is a paperless assignment. You need only turn in the program electronically.
Solution
The instructor's solution is now available here. A
compiled executable derived from the solution is available for you to try
out. The solution executable can be found at ~cs367-3/Solutions/One/sets
Late Policy
Late assignments will not be accepted. If you feel you truly have a
justifiable excuse for turning in the assignment late, you must clear it
with me at least one day in advance. (I do not plan on clearing any such
requests.)