CS1322: Programming Assignment #3 - Fall 2002. Assigned: Phase 2 CheckOff: Monday, October 7th, 2002 at 23:59:59 Phase 4 Checkoff: Wednesday, October 16th, 2002 at 23:59:59 DUE Date: Wednesday, October 16th, 2002 at 23:59:59 Program Title: Telegram for Bugs Files Provided ==================================================================== o p3.nfo.txt - this file o P3Type.java - Interface needed for P3 o IOHelp.txt o TricksandTools.txt Learning Objectives ==================================================================== o File I/O o Useful Java Tools o Hashtables. HASHTABLE OVERVIEW ==================================================================== A HashTable is a data structure which allows for the retrieval of the information associated with a specified key value. They are made from HashNodes. Thus you will add data to a HashNode and then add the HashNode to the HashTable. A HashTable first applies a hashing function to the key value to limit its range to a reasonably small number. That hash value is then used to index into an array to find the appropriate data. Since the hash function is not one-to-one, it is possible that multiple key values could hash to the same value- if this is the case, then a "collision" occurs, and it must be resolved. Hashtables are useful for finding the data quickly- the hashing operation occurs in O(1) time, and then, as long as the number of collisions is small, the data may be found with just a few operations- making for a very fast search. It should be noted and emphasized that HashTables are based on an array. A HashTable holds an array- what exactly that array holds depends on the collision resoulution strategy used in the HashTable. The size of the array is important- if the array is too small, there will be many collisions, and operations will not be efficient. If the array is too large, then there will be wasted space. What is collision resolution? Collision resolution is the process by which entires in a hashtable that have the same hash value are handled. Typical methods include: External chaining: The HashTable is an array of linked lists. When a value is added to the table, it is hashed, then added to the appropriate linked list. When a key is searched for, it is hashed, then the correct linked list is searched for that key and the associated data. Open Addressing: When a value is added to the HashTable and the desired space is full, an algorithm is applied to continue searching through the array to find an empty space to put the element in. There are two common forms: - linear probing: the array index which is being attempted is increased by a fixed ammount (i.e +1 each time) until an open space is found. - quadratic probing: the array index which is being attempted is increased by an increasing ammount (i.e +1, then +2, then +3) until an open space is found. When searching for the data, the same probing function is applied until the data is found. Coalesced Chaining: An extra area (cellar) is allocated at the end of the array (beyond the range of the hashing function), and when a collision occurs, the data is stored in the first open space in the cellar. When searching for the data, if it is not in the initial space, the cellar is searched. Multiple Record Buckets: Have room for a fixed number of collisions to occur at each hash value (i.e. the HashTable is a 2D array). When searching for the data, look in each of the spaces at that hash value. PROGRAM OVERVIEW ==================================================================== You will be making a simple telegram/postoffice for this assigment. In order to accomplish this, you will make use of the data structre - HashTable. You will use external chaining as the collision resolution algorithm. PROGRAM WALKTHROUGH ==================================================================== PHASE I - RECORD CLASSES (Mail.java and MailBox.java) This phase should contain no more than 1 hour worth of coding. If you are spending significantly more time than this then please come see a TA. All the TA's are more than happy to help. ==================================================================== Mail.java Since a post office handles mail, it will be useful to make a class for mail. Make a Mail class that implements P3Type. This class should have instance variables to store such things as who the mail is from, who the mail is to, and what the message is. Thus, there should be three private variables, all of which are Strings. Call these variables: strFrom; strTo; strMessage Make accessors and modifiers for of these variables. Next, you need to make a constructor which takes in the message, who the message is from, and who the message is to. The constructor should set each variable appropriately. public Mail(String message, String from, String to) Lastly, make override the toString method that will return a string which looks like... To: Honey Bee From: Lovely Flower Message: I don't like you stealing my sweets! ********************************************************************* MailBox.java Make a MailBox class that also implements P3Type and make it hold the first and last name of the person who "owns" this mailbox. The mailbox will also contain all the mail that the person has received. Create three private instance variables: String strLName; String strFName; Vector vMail; For information on how to use Vectors and to find important methods in the Vector class, consult TricksandTools.txt Make sure you create accessors and modifiers for the person's last name and first name. Now create a constructor which will take in a person's last and first name. You should set these two variables appropriately and initialize the Vector. public MailBox(String last, String first) After completing that, you need to create a method for "placing" a piece of mail into the persons mailbox. Call this method addMail. It should take in Mail and add that mail to the vector of mail. Now you are going to want to write a method that will return all the mail that a person has. After people take mail out of their mailbox, the mail is no longer there. When this method is called, not only should it return all mail that is in the mailbox, it should also contain no more mail (unless a person sends mail to them after they check their mailbox). This means the you should "reset" your mail Vector. This method - called getMail - will return an Enumeration containing all the Mail currently in the mailbox. Look in the TricksandTools.txt file for information about Enumeration as well as other useful tools in Java. Create a toString method which will return a String which contains the name of the person who the mailbox is issued to as well as the number of pieces of mail the person has in their mailbox. an example of a String returned is... FName LName has X piece(s) of mail. so, Really Popular has 1 piece of mail. but, Not Me has 4 pieces of mail. Lastly, create an equals method that will compare two mailboxes to see if they are equal. Two mailboxes are equal if they are "issued" to the same person (meaning the last name and first name of the two mailboxes are the same) END OF PHASE 1!!! ==================================================================== PHASE 2. WORKING WITH FILE I/O (FileChanger.java) INSTANT FEEDBACK PHASE This phase should contain no more than 2 hours worth of coding. If you are spending significantly more time than this then please come see a TA. All the TA's are more than happy to help. ==================================================================== FileChanger.java This file will allow you to read input from a file and write information to a file. If you read IOhelp.txt, this phase will be alot easier. Create the appropriate variables needed for file io. Also, create a private instance variable for the name of the file (strFileName) The constructor for this class should take in a String - the fileName The file name should be set appropriately. Next create a method that will initialize all the buffers needed to read the Objects from the file. This method will return true if the file is found. It will return false if the file does not exist public boolean initReader(){ } Create a method that will initialize all the variables needed to write to the file public void initWriter(){ } Now create a method that will return the next Object from the file. If it encounters the end of the file, then null should be returned. public Object nextObject(){ } Next you need to write a method that will write an Object to the file. public void writeObject(Object toWrite){ } Write a method that will close all the buffers open to read the file public void closeRead(){ } Write a method that will close all the buffers open to write to the file public void closeWrite(){ } Write a main to test this class. Use your record classes written above to test this class. One way of doing this would be to create a bunch of Mail and save it to a file. Then read that file and print out all the Mail that is in there. END OF PHASE 2!!! Submit this phase to webwork for an autograded checkoff. File(s) to submit: FileChanger.java ==================================================================== PHASE 3. HASHNODE IMPLEMENTATION (HashNode.java) This phase should contain no more than 30 minutes of coding. If you are spending significantly more time than this then please come see a TA. All the TA's are more than happy to help. ==================================================================== A HashNode should contain Three private instance variables. One is a reference to another HashNode. The other two are Objects - one object is the key, and the other is the data. HashNode next; Object key; Object data; The constructor for this class should take in the key and the data; public HashNode(Object key, Object data); Make an equals method which will check to see if two HashNodes are equal Two HashNodes are equal if they have the same key. END OF PHASE 3!!! ==================================================================== PHASE 4. IMPLEMENTING a HASHTABLE (HashTable.java) This phase should contain no more than 3 hours worth of coding. If you are spending significantly more time than this then please come see a TA. All the TA's are more than happy to help. ==================================================================== For this assignment you will be using external chaining as the hashtable's collision avoidance. Call the hashtable hTable The constructor should take in an int that will be the size of the array. The constructor will initialize the array to the given size. You will need to code the following methods add(Object key, Object data) get(Object key) remove(Object key) elements() rehash(int iSize) size() toString() The add method will add the data at the appropriate location. The location to add the data is found by using the key passed in. Look up hashCode() in the Object class. **NOTE that the value returned from hashCode may be negative The get method will return the data that is associated with the given key. It will return null if the data is not found. The remove method will remove a HashNode from the Hashtable. The Node that will be removed will be the Node that contains the key. Make sure to return the data that is held in the HashNode deleted (the data not the key). If no HashNode is in the HashTable with the key, null is returned. Elements should return an enumeration of all the data in the HashTable...they should be HashNodes The rehash method should resize the HashTable to the given size and readd all the data to the appropriate location of the HashTable size will return the size of the hashtable toString will return a String representign all of the elements in the hashtable Make sure to write a main to test this class END OF PHASE 4!!! Submit this phase to webwork for an autograded checkoff. File(s) to submit: HashTable.java ==================================================================== PHASE 5. MAKING the POSTOFFICE (Manager.java, PostOffice.java) This phase should contain no more than 5 hours worth of coding. If you are spending significantly more time than this then please come see a TA. All the TA's are more than happy to help. ==================================================================== Manager.java This class will represent the person running the post office. All this person is in charge of is performing operations given to him. The only functionality of the assistant at this point will be: Help Customer Add More Rooms View All MailBoxes and Leave for the Day When a customer comes into the post office, then the manager will be able to Issue New Mailbox Remove a Mailbox Send a Telegram and Retreive All Telegrams Now that we know the basic operations of th manager, let's make the PostOffice class so that the Manager can manage HIS PostOffice. We will come back to code this class after we do the post office class ********************************************************************* PostOffice.java Make the PostOffice class implement P3Type. This class should contain only one instance variable - A HashTable called htExpress. The default size should be set to the default size in P3Type - 10. The first method that you want to write is one which allows the post office to issue another MailBox. Call this method issue. It wil take in the new Mailbox and should add this mailbox to the Hashtable. REMEMBER, the key is the persons last name. A person should not be allowed to have two mailboxes. public void issue(MailBox mbToAdd) The second method you will need to write is one that will retrieve all the mail located in a person's mailbox. The person's last name will be passed in to this method. If the person does not own a mailbox at this post office, then return P3Type.NO_MAILBOX. Otherwise the method should return a String representing all the mail that the person has received. public String retrieve(String strLName) Now write a method called send(Mail toSend). This method will return an int. If the person trying to send the mail has never been issued a MailBox then return P3Type.BAD_SENDER. This has first priority. If the recipient of the mail has never been issued a MailBox before, then return P3Type.NO_RECIPIENT. Otherwise add the mail to the recipients MailBox and return P3Type.MAIL_SENT. In order to write this method, you will need to get the last name of the sender and recipient. You can assume the last name of the person is all of the characters after the last space. It may be beneficial to use StringTokenizer. public int send(Mail toSend) Next write a method that removes a MailBox from the PostOffice. This method should be called remove. It will return the number of unread telegrams in a person's mailbox when it was deleted. If that MailBox has never been issued, then return P3Type.NO_MAILBOX_NUM public int remove(String strLName) Another method that will be needed is one to retrieve all of the mailboxes in the Post Office. This can be done by writing a wrapper method for the HashTable elements(). All that needs to be done here is to return the Enumeration of the HashTable. public Enumeration allBoxes() Lastly write a method that will resize the HashTable (This will make it quicker for the assistant to find the correct mailbox). This method will double the current size of the hashtable. public void resize() Remember to test this class ********************************************************************* Now that we have coded the Post Office class, let's go back to the Manager. The manager class needs to implement P3Type and hold 3 private instance variables...a String for the customer's last and first name (strCustLName and strCustFName), and a PostOffice Make a method called managerActions() that returns a boolean The boolean will be true if the manager has actions to perform and will be false when the manager is ready to go home. Have this method print out P3Type.INIT_ACTIONS. Then wait for the user to make a choice. To figure out how to wait for user input from the keyboard read the file IOhelp.txt. The initial actions menu should look like this... 1) Help Customer 2) Add More Rooms 3) View All MailBoxes 0) Leave for the Day If the user enters the selction 1, then you should prompt for the customer's name and go to another method called customerHere() you should continue looping to this method until it returns false (meaning the customer left) If instead the selection choice were 2, then the manager would resize his post office. If 3 were selected, all of the mailboxes in the post office would be printed. If the selection 0 were chosen, then false will be returned and the program will exit. The method customerHere() will take in a String strName and return a boolean. The return will be true if the customer still wants to do something at the postoffice. If the customer is done, then false will be returned. First, you should print out the menu P3Type.CUST_HERE which looks like this: 1) I want a mailbox at this post office. 2) I no longer want a post office at this mailbox. 3) I want to send a telegram. 4) I want to read all of the telegrams I have received. 0) Okay, I am done. If the customer chooses 1 then you will make a new mailbox and add it to your post office. If the customer chooses 2, you will try to remove the persons mailbox and then do one of two things: - Print P3Type.NO_MAILBOX if the person does not have a mailbox - Or print P3Type.NUM_TELEGRAMS + the number of telgrams the person had If the customer chooses 3, then you should prompt for the person who they want to send the message to, and then prompt for the actual message. Next send the message. And print out an appropriate message depending on the return value Lastly, if the customer chooses the 4 option, then retrieve all the telegrams in his mailbox and print them to the standard out. If 0 is selected, then you should return false and the managerActions menu will be displayed. Be SURE to test this class and make sure everything is working up to this point (Since this is a small town, no two people have the same last name) END OF PHASE 5!!! ==================================================================== PHASE 6. SAVING THE POSTOFFICE (Updates in Manager.java and PostOffice.java) This phase should contain no more than 1 hour worth of coding. If you are spending significantly more time than this then please come see a TA. All the TA's are more than happy to help. ==================================================================== Inside of PostOffice.java, add one method. This method will be called leavingForTheDay(). This method will be called when the manager chooses the option 0 (Leave for the Day). In this method, you will save all of the MailBoxes in the PostOffice to P3Type.POST_OFFICE. ********************************************************************* Inside of Manager.java, you will have to do two things. First, make it call leavingForTheDay when the manager decides to leave for the day (option 0) Next, you will need to read from the file P3Type.POST_OFFICE and add all of the mailboxes into the PostOffice. You can do this by calling issue(Mailbox) ********************************************************************* Lastly, create a file called P3.java which will serve as the driver for this project. This class should make an instance of manager and keep calling managerActions() until the method returns false in which case it prints P3Type.GOOD_BYE END OF PHASE 6!!! ==================================================================== COMPILERS: ======================================================================== As a reminder, make sure that your program compiles and runs as expected under Sun's JDK 1.3.1. Read the PROGRAM RESTRICTIONS section to see what you can and cannot use to implement this program. COMMENTS ======================================================================== You must comment your code thoroughly. Each method should have a proper javadoc comment with the param and return tags where needed. Each instance and static variable should be javadocced. Any code that is not obvious should be explained briefly in a comment. All closing braces should be commented. TURNIN ======================================================================== Files to be turned in via Webwork: (all .java files you made for this program) This includes but is not limited to - Mail.java - MailBox.java - FileChanger.java - HashNode.java - HashTable.java - Manager.java - PostOffice.java and - P3.java