524 lines
21 KiB
Plaintext
524 lines
21 KiB
Plaintext
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 <enter>
|
|
From: Lovely Flower <enter>
|
|
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 |