/ruby/homes/ftp/pub/bvz/classes/cs302/bin/dsearchand follow the instructions for entering queries. Warning: dsearch expects a file named roster to be present in the directory in which you type the command. Hence you should either copy the roster file from the lab4 directory to your own directory before typing the command or you should cd to the cs302 bin directory.
Notice that dsearch does not read the roster file from stdin nor does it take it as an argument on the command line. As you will see later, the roster file is hardcoded as a constant.
In order to manage the compilation and linking of your files for this assignment, you will also create and hand in a makefile.
An abstract data type for searching should be able to support three basic operations:
In this part of the lab you will write an abstract class declaration for a search type, write dlist and hash table implementations, and test the implementations.
The input file for this problem consists of a roster of football players. The format of the input file is:
last name first name height position year state hometown
(string) (string) (string) (string) (string) (string) (one or more
strings)
An example line would be:
Colquitt Jerry 6.4 QB Sr Tennessee Oak Ridge, TNAn example input file can be found in roster. You cannot make any assumptions about how many lines of data are in the input file. You must read in the input file using the Fields class.
Our driver program produces the output for you so you do not have to worry about formatting the output.
The key for each entry in the input file consists of a first name and a last name. The search data structure will expect the first name and last name to be packaged into an object of type Name that has the following public interface:
class Name {
public:
Name(string fname, string lname);
Name(const Name &); // copy constructor
bool isEqual(Name key); // returns true if the parameter key matches
// this object's name
bool lessThan(Name key); // returns true if this object's name is less
// than the parameter key.
int hash(int tableSize); // returns a hash value for the name
};
You will need to complete the declaration of this class by filling
in the protected data members. You will also need to write the
methods for this class. Two keys are equal if both their last names
and first names are identical. One key is less than another key either
if: 1) its last name is less than the other key's last name, or
2) its last name is equal to the other key's last name but its first
name is less than the other key's last name. For example, "Jamal Lewis"
is less than "Lennox Lewis" since the last names are identical and "Jamal"
is less than "Lennox". Strings support the < and ==
operators so you can compare strings using these two operators.
You should modify the partial declaration for Name that can be found in Roster.h. You should put your method definitions for Name in Name.cc. The hash method has already been defined for you in Name.cc.
You will need to store each line of input into an object of type RosterRecord. A RosterRecord needs to support the following public interface:
class RosterRecord {
public:
RosterRecord(string fname, string lname, string ht,
string pos, string yr, string players_team, string home);
string getLastName(); // returns the player's last name
string getFirstName(); // returns the player's first name
string getHeight(); // returns the player's height
string getPosition(); // returns the player's position
string getYear(); // returns the player's year
string getTeam(); // returns the player's team
string getHometown(); // returns the player's hometown
Name getKey(); // packages the last name and first name
// into a name object and returns it
}
You will need to complete the declaration of this class by filling
in the protected data members. You will also need to write the
methods for this class. The declaration can be found in
Roster.h. The method definitions should be
placed in RosterRecord.cc.
One complication you will face is that the hometown may consist of multiple fields. You will need to concatenate these fields together to form one string. You can use the string class's += operator to do concatenation. For example:
string a = "Hello";
string b = "World";
string c += a + " ";
c += b; // c = "Hello World"
Remember to put blankspaces (" ") between the fields.
class SearchType {
public:
virtual ~SearchType() {}
virtual void insert(Name key, RosterRecord *value) = 0;
// remove returns true if it successfully removes a record with this
// key from the search structure. remove returns true if it cannot
// find a record with this key in the search structure.
virtual bool remove(Name key) = 0;
// find returns a pointer to a RosterRecord if it finds a record with
// this key in the search structure. find returns 0 (i.e., the null
// pointer) if it cannot find a record with this key in the search structure.
virtual RosterRecord *find(Name key) = 0;
};
You should declare a subclass of SearchType called DlistSearch and add its declaration to search.h. DlistSearch should support exactly the same public interface as SearchType, and in addition it should add the following constructor declaration:
DlistSearch(); // performs any necessary initializationThe DlistSearch class should be implemented using a doubly linked list. A template Dlist class has been provided for this purpose. Notice that search.h already contains the appropriate include file for the Dlist template class. The Dlist template class takes one type argument, which is the type of the value being stored in the Dlist. For example:
DlistYou should place your method definitions for DlistSearch in DlistSearch.cc.x; // A dlist that contains integers Dlist y; // A dlist that contains pointers to Names
You should declare a subclass of SearchType called HashTableSearch and add its declaration to search.h. HashTableSearch should support exactly the same public interface as SearchType, and in addition it should add the following constructor declaration:
HashTableSearch(int tableSize); // performs any necessary initialization.
// tableSize is the desired hash table
// size.
The HashTableSearch class should be implemented using a hash table. A template
HashTable class has been provided for this purpose.
The search.h file
already contains the appropriate include file for the HashTable template class.
The HashTable template class takes two type arguments, which are the type of the key and the the type of the value being stored in the hash table. For example:
HashTableThe HashTable class assumes that the value type contains a method called getKey that returns the value's key and that the key type contains a method called hash that returns the key's hash value. You should look at the top of the HashTable.h file to see how the HashTable class is meant to be used and what arguments must be passed to its methods. Although you may look at the protected part of HashTable and at HashTable.cc, you are not expected to know how the HashTable is implemented (indeed you are not supposed to know!). You should place your method definitions for HashTableSearch in HashTableSearch.cc.x; // A hash table that stores pointers to // personnel records and which uses an // integer as a key
In order to test your implementations of DlistSearch we have provided a driver program and placed it in dsearch.cc. You will create a driver program called hsearch.cc to test the HashTableSearch structure. You will find that because of inheritance, the two files will be identical except for one line of code. This should show you how easy it is to switch implementations when both implementations use the same interface.
The driver program is supposed to read in the roster file, store the records in the roster file into the appropriate search structure, and then perform queries on these search structures. The querying and output formatting code have already been written for you. You will need to write the code to read lines from the roster file, convert the lines to RosterRecords, and insert the records into the search structure. The name of the roster file has been hardcoded into the program using a constant called INPUT_FILE. Hardcoding the file name may seem somewhat inflexible but it is done in many production, data processing systems because the names of the files are fixed in advance and it prevents a user from incorrectly specifying a file name.
In sum, for this portion of the lab you must: