CPS 100E, Fall 1996 Lab 11

Maps, Inheritance, Hashing, and US Geography

(You may find it easier to read this lab using Netscape or another browser, the URL is http://www.cs.duke.edu/~ola/courses/cps100e/lab/lab11.html)

The goals of this lab include doing the specific tasks outlined below and understanding general concepts behind the tasks.


A Map class (sometimes called Table or Dictionary or Associative Array class) takes keys and maps them to values. For example, the telephone book maps names to telephone numbers. You could also map words to the number of times that words occur.

In this lab, we will be mapping names of cities/towns, etc. (like Springfield, Chicago, etc.) to a list of records that contains every city/town in the US with the given name. For example, if we type "Durham", the list might look like the following:

City and State Population Latitude Longitude
DURHAM CA 4784 39 35 58 N 121 49 40 W
DURHAM CT 2650 41 28 26 N 72 40 55 W
DURHAM KS 119 38 29 6 N 97 13 37 W
DURHAM NH 9236 43 8 22 N 70 55 24 W
DURHAM NC 136611 35 58 50 N 78 54 54 W
DURHAM OR 748 45 23 41 N 122 45 27 W

Lab 11 table of contents

[ Introduction to Lab | Compiling/Running/Testing useplace ]

[ Modifications to Classes | Submit | Extra Credit ]

Introduction to Lab

In this lab, we will take advantage of inheritance to build two versions of a map. These versions both inherit from a base class Map. The classes are:

You'll also use inheritance to help process all the entries in a map by deriving new classes from the MapBase class.

In the first part of the lab, you will compare two implementations of the Map class and time how long it takes each implementation to read entries from a database.

In the next part of the lab, you will implement two derived classes of the MapBase class: (PrintState and Distance so that the PrintState class can compute the population of a state, and the Distance class can find the city that is closest to a given coordinate (given in latitude and longitude.)

back to lab contents

Compiling/Running useplace

In this section of the lab you'll copy files and then compile and run the useplace program.

First change into your cps100e subdirectory (type pwd to verify where you are). Create a lab11 subdirectory by typing mkdir lab11 and change into this subdirectory (be sure to check that you're in the lab11 subdirectory.) Now copy the files for the lab (don't forget the . when copying).

cp ~ola/cps100e/lab11/* .

You should see the files listed below (these are links to the files in case you use Netscape, and for users outside of Duke).

Be sure you're in the lab11 subdirectory, and check to see that all files are there (type ls). Next Type

         ln -s ~ola/data data
To link (not copy) the data directory, (You should not copy the files because they are large), so you can access them by linking to the data directory. The data directory stores lots of data files. The three we'll be using are smplaces.txt, medplaces.txt, and places.txt (these are small, medium, and large respectively).

Type ls -l data. You should see something that looks similar to the following:

lrwxr-xr-x 1 mloeb grad 26 Oct 2 12:06 data -> /afs/acpub/users8/ola/data

This shows that you've linked to ola's data directory.

Next, compile the first version of the program by typing: make useplace. This should compile the files and link them together with the library libtapestry.a. Now, run the program by typing: useplace at the prompt. First, usplace will ask you if you want to use a map based on a hash table, or by a table based on unsorted vectors. Type 'u' to choose a map that uses unsorted vectors as its data structure, or type 'h' to choose a map that uses a hash table as a data structure. After you choose the type of map, you want to use, you will see a menuing structure similar to the menus in previous labs (but when you look at the code you'll see some differences that will be explored in the inlab exercises.)

Testing Maps Based on Hash Table vs. Maps Based on Unsorted Vectors

You'll time two versions of the Map class for the medium sized text file data/medplaces.txt. The code for timing how long it takes to read a file has been given to you. Record the time it takes for each kind of Map, you'll need to report these times in your README file for data/medplaces.txt. You'll also need to report in your README file the total number of citites in the medium sized data base, the number of cities in North Carolina, and the number of cities in your home state. Be sure to record these NOW, preferably in your README file.

Note: It may take a few minutes to read in the medium sized file using an unsorted vector.

back to lab contents


Modifications to Classes

In this section you'll make several modifications. Use the file data/smplaces.txt for debugging. When you think your code is working with all the changes done you should then use the large file data/places.txt to answer the inlab questions for this part of the lab.

IMPORTANT: Make sure you use a hash table when you load the large file, places.txt. It took me 11 minutes to load this file on acpub using the UVMap class.

  1. Modify the PrintState class so that it tallies the population of the input state. The total population of the state should be printed in the Report member function of the PrintState class. To do this you'll edit the implementation of PrintState stored in printstate.cc. You should study the function named Function (not an informative name?).

    The function Function is called by the Map class for every element in the map class. You'll see that the there are two parameters:

    • the string is the name of a city/village
    • the list is all the places that have that name (recall the map maps cities to Lists of places).

    The GetName function is declared in place.h and implemented in place.cc -- it is one of many Get functions that return values of a place (e.g., land area, coordinates of latitude and longitude, etc.). You'll need to add a function GetPop declared in places.h and defined in places.cc. The function simply returns the value of myPop.

    After implementing GetPop you'll need to call the function and accumulate a sum in the functions of the class PrintState. You'll need to think about defining a variable to accumulate the sum, initializing it, and printing the result. Use the variable myCount as a model.

    Remember that the map class takes care of calling Function for every element in the map but as you can see in DoPrintState in useplace.cc you call the Report function.

  2. Implement the DoNearest function in useplace.cc so that it finds the city nearest to a given location. You'll enter a location using latitude and longitude and the program should find the closest city. You may be interested that the latitude and longitude of Chapel Hill are 35.927613 N and 79.040627 W, respectively. You'll find the closest city by doing the following:
    1. Prompt the user for a latitude and a longitude, get these values using GetLatitudeand GetLongitude that allow you to enter values like 35.92, but which process values in the form needed by the data base.

    2. Modify and use the class Distance class defined in distance.h and implemented in distance.cc to keep track of the closest city to what the user enters. You'll need to construct distance by passing in the latitude and longitude so that when Distance::Function() is called for every value in a map it will be able to calculate how far each city is from the coordinates the user enters and remember the closest one (you'll need to define several private variables for the class Distance.)

    3. You'll need to modify Distance::Report() to print out the name of the City and State that is closest to the given location. To do this you'll probably want to store a Place object in the private section of Distance, but you'll need to think about this. You should model what you write based on the class PrintState.

  3. Modify the DoNearest function so that it asks the user for a radius r (remember to use getline and atof to convert the string to a double). Your program should print out a list of cities that are within an r mile radius of the input location (latitude and longitude) -- you should be able to do this by modifying slightly the Distance class you wrote in the previous part. You should have it still report the closest city so that when you're done with the lab it finds all cities within a specified radius as well as the closest of these.
back to lab contents

Submitting The Lab

To submit assignments you'll run the command below, but substitute your section number (1, 2, or 3) for N.
    submit100e lab11.N README useplace.cc distance.cc distance.h 
printstate.cc printstate.h

You can enter the files in any order.

Remember that every assignment must have a README file submitted with it (please use all capital letters). Include your name, the date, and an estimate of how long you worked on the assignment in the README file. You must also include a list of names of all those people with whom you collaborated on the assignment.

back to lab contents


Extra Credit

For Extra credit, you should sort the list of cities that are within an r mile radius of the given coordinate so that the city that is closest to the given location is printed out first, the city that is the 2nd closest to the given location is printed out second, etc.

More Extra Credit

Write another main program that uses the Hmap class to read in a text file (i.e. one of Shakespeare's plays), and computes the number of unique words in that file and how many time each word occurs. You'll map strings to integers where the integer is the number of times the string occurs. You should add a member function PrintHashStats to the Hmap class so that the user can do the following:

  1. Print out the longest chain in the Hash Table and its length.
  2. Print out the Average length of a chain in the Hash Table

To submit the extra credit, you'll run the command below, but substitute your section number (1, 2, or 3) for N.

    submit100e lab11.N.xtra hmap.h hmap.cc useplace.cc yourprogram.cc 

yourprogram.cc is the name of the program that you typed in for more extra credit. You can enter the files in any order.

You also must turn in the inlab questions either by turning in the sheet during lab or by submitting the answers with your README.