SlideShare a Scribd company logo
1 of 9
Download to read offline
Assignment4
Assignment 4: Hashtables
In this assignment we will use a rhyming dictionary and loading it into a hashtable and using the
hashtable ADT(abstract data type) to implement a bad poetry generator.
Objectives
TODO #1: Implement a hashtable
TODO #2: Loading the dictionary
Optional:
TODO #3: Removing unrhymable words
Testing
Testing can be done through Maven with the command,
mvn test
To run more specific tests, run the command
mvn -Dtest=AssignmentTest#TESTCASEHERE test
where TESTCASEHERE is the test case you want to run. These test cases can be found in
src/test/java/AssignmentTest
Ex: mvn -Dtest=AssignmentTest#test_2_puts test
The results can be found in the command line or in target/surefire-reports/AssignmentTest.txt
after execution.
Part of grading will be these test cases.
Alternatively,
You can use the main method found in RhymingDict.java. In fact, the test cases are dervied from
that main method.
To Do 1: Implementing a Hashtable
Youll be implementing a hashtable class called MyHashtable. It implements the interface
DictionaryInterface.
The hashtable youll be making will use Strings as the keys and Object as the values. Similar to
linked lists, by storing Object as values, you can store any kind of object in the hashtable.
To implement a hashtable:
Use a protected inner class inside MyHashtable called Entry. This inner class stores Key/Value
pairs. So it has two fields:
String key
Object value
It also should have a constructor for initializing the key and value.
Your hashtable will define three protected fields (remember that protected means that the field can
only be accessed from within the class or by any child class of the class).
int tableSize - the size of the array being used by the hashtable
int size- the number of key/value entries stored in the hashtable
MyLinkedList[] table - an array of MyLinkedList. The reason that each element of the array is a
linked list is to store multiple entries which collide, that is, for which the hash for the different keys
is the same index in the table.
Youll be implementing the following methods on MyHashtable
public boolean isEmpty()
Returns true if the hashtable is empty, false otherwise. You can use the size field to determine this
easily.
public int size() Returns the size (number of key/value pairs stored in the hashtable). Theres more
info about how to implement this method below.
public Object put(String key, Object value)
Adds a new key/value pair to the hashtable. If the key has been previously added, it replaces the
value stored with this key with the new value, and returns the old value. Otherwise it returns null.
public Object get(String key) Returns the value stored with the key. If the key has not previously
been stored in the hashtable, returns null. Theres more info about how to implement this method
below.
public void remove(String key) Removes the key/value pair associated with the key from the
hashtable. Theres more info about how to implement this method below.
public void clear() Empties the hashtable. The easiest way to do this is to just set table equal to a
new fresh array - the old one will be garbage collected (memory reclaimed) by java. Remember to
set size to 0 as well.
public String[] getKeys() Returns an array of all the keys stored in the table. This function is
necessary because having all the keys is the only way to iterate through the values in a hashtable.
Theres more info about how to implement this method below.
public MyHashtable(int tableSize) The constructor for the hashtable. Takes an argument that is
used to set the size of the array used to store the hashtable. Initialize tableSize, table, and size.
Hash Codes
In a hashtable, to compute an index into the array given a key you compute a hashcode for the
key. Since our keys are all Strings, well be using the method hashCode() which is already
provided on Strings.
As an example:
The integer returned by hashCode() ranges over the full range of negative and positive integers.
So the number could be way out of range for indexing our table (depending on our array size) or
could be negative, which we definitely cant use for indexing our array. So well use the same trick
we talked about with array-based Queues of using the modulo operator to get the number within
range:
Math.abs() gets the absolute value (to get rid of negative numbers) and % tableSize puts the
number into the range 0..tableSize-1 by returning the remainder after dividing by tableSize.
get(), put() and remove() all take a key as one of the arguments. So these functions will all need to
compute an array index from the key to look in the table.
Remember that our table is an array of type MyLinkedList, where each item in the linked list is an
Entry (storing a key and value). Why cant we just store the values directly in the table? The reason
is that hash functions can result in collisions, where two different keys get mapped to the same
array index (because they have the same hash code). So we have to story our entries(key/value
pairs) in lists.
In a hashtable, this list is called a bucket (or sometimes a slot). Each list in the table stores entries
whose keys result in hash collisions. But if our hash function is good, it will spread the data out
well so that no bucket ever gets too long.
Implementing Object get(String key)
To implement Object get(String key)you need to:
Compute an array index given the key (see above).
If that location in the table is null, that means nothing has been stored using a key with this hash
code. So we can return null.
If the location isnt null, then it contains a MyLinkedList which is the bucket for all keys that collide
using the hash function.
Linearly search through the bucket (the list), comparing the key for each entry with the key passed
into get(). If you find a match, return the value. If you get to the end of the list without finding a
match, return null (nothing stored for this key).
Implementing Object put(String key, Object value)
To implement Object put(String key, Object value)you need to:
Compute an array index given the key.
If that location in the table is null, that means nothing has been previously stored using a key with
this hash code.
a. Create a new MyLinkedList to be the bucket.
b. Add the new Entry for the key/value pair to the list.
c. Set this location in the array equal to the new bucket (list).
d. Increment the size (the number of unique keys you have stored).
If the location in the table isnt null, that means keys with this colliding hash code have been
previously stored. So our new key/value pair might be a key thats already been added (in which
case we replace the value), or a brand new key (in which case we add a new Entry to the bucket).
a. Linearly search through the bucket (the list) stored at this array location comparing the key for
each entry with the key passed into put(). If you get a match, this means this key as been
previously stored. Save the old value in the Entry (so you can return it) and replace it with the new
value. You dont need to increment the size since youre not adding a new key.
b. If you dont find the key in the bucket, then just add a new Entry (with the key and value) to the
beginning of the list. Increment the size.
Return the old value if storing using an existing key (step 3.a above), otherwise return null if youre
adding a new key (step 2 or step 3.b).
Implementing void remove(String key)
To implement void remove(String key) you need to:
Compute an array index given the key.
If that location in the table is null, then this key has definitely not been used to store a value. No
need to do anything.
If the location in the table has a bucket, we need to linearly search it to see if it contains an Entry
with the key. If you find an Entry in the bucket (linked list) with the key:
a. Remove this Entry from the bucket.
b. Decrement size (the number of unique keys stored in the hashtable).
Implementing String[] getKeys()
To implement String[] getKeys() you need to:
Create a String[] with a size equal to the number of unique keys in the hashtable (hint: one of our
hashtable fields is keeping track of this).
Iterate through the hashtable array. For each table location that isnt null:
a. Iterate through the bucket (linked list), getting the key out of each Entry and storing it in the
array of strings you created in step 1. Youll need some kind of counter to keep track of where in
the array of Strings youre adding the key.
Return the String[]
Extra Functions for Experimentation
Two extra functions that are not part of the DictionaryInterface have been provided on
MyHashtable to let you experiment with how collisions change as you change the table size of
MyHashtable. Theres no To Do item associated with these functions; theyre just for your own
experimentation.
public int biggestBucket()java returns the size of the largest bucket (the most collisions) in the
hashtable.
public float averageBucket() returns the average bucket size.
Together, these two functions give you a sense of how frequently collisions are happening in the
hashtable. As you make the table size smaller, the number of collisions will go up. In the limit of
creating a hashtable with 1 table entry, then every key/value pair is stored in one big list.
On MyHashtable theres also an implementation of public String toString(). This allows you to print
out the key/value pairs in your hashtable. Theres also a method in RhymingDict.java called public
void testDictionary(DictionaryInterface dict). You can use this method to test your hashtable once
youve implemented it. It does some simple adding, removing and replacing of key/value pairs and
prints out the hashtable so you can confirm your table is working correctly.
Rhyming Dict
After youve made your hashtable, the remaining two To Do items are in RhymingDict.java.
RhymingDict.java already does the following:
Creates a MyHashTable with size 20,000.
The keys well use in this hashtable are rhyming groups (like AA1 V AH0).
The values well use in this hashtable are MySortedLinkedList. Each MySortedLinkedListwill store
individual words sharing a rhyme group.
Were providing you with a working version of MySortedLinkedList.
Does the file management to read each line from the CMU Pronunciation dictionary
The CMU Pronunciation dictionary is a free data source of how each word in English is
pronounced, useful for text-to-speech or rhyming applications.
Writes poems
Picks two rhyming groups at random from an array of keys.
Gets the MySortedLinkedList of words for each group.
Picks two random indices for each list (based on the length of the list), and uses these two get four
words, two words from each list.
Uses those words to make a poem, e.g.
Note: we removed most of the bad words from the dictionary, but the poems might still sometimes
make bad or offensive juxtapositions
You need to implement the following:
TO DO # 2: Store each line from the CMU dictionary in the hashtable.
This involves implementing the method storeRhyme().
Use getWord() and getRhymeGroup() to get the word and rhyme group for the line.
Lookup (get) the key (the rhyme group) in the Dictionary (hashtable). If the result is null, then this
rhyme group has not been added before.
Create a new MySortedLinkedList.
Add the word to the list.
Put the key (rhyme group) and value (list) in the Dictionary.
If the result of the lookup (get) isnt null, then weve already started a word list for this rhyme group.
Add the word to the list returned by get(). Nothing needs to be added to the Dictionary since the
list is already in the Dictionary.
(Optional) TO DO #3: Remove the unrhymable words from the dictionary.
Some words are in a rhyme group by themselves. That means that nothing rhymes with them. We
want to get rid of those before trying to make poems. Youll do this by implementing
removeUnrhymables().
Use getKeys() to get an array of all the keys.
Iterate through all the keys, retrieving the value (linked list) associated with each key.
If the length of the list is 1, that means theres only one word in the list: nothing rhymes with it. Use
Dictionary.remove() to remove this entry.
If youre curious to see what words dont have rhymes (at least according to the CMU pronunciation
dictionary), you could add a println to print out the words as you remove their corresponding
entries. If you do this, dont forget to comment it out before you turn it in.
Example Input and Output
RhymingDict can take 0, 1 or 2 command line arguments.
The first argument is a seed for the random number generator. If you provide 0 arguments this
defaults to the current system time.
The second argument is the number of poems to generate. If 0 or 1 arguments are provided, this
defaults to 3.
For this command line:
the output should look like:
Complete code in Java
The hashtable you'll be making will use Strings as the keys and Object as the values. Similar to
linked lists, by storing Object as values, you can store any kind of object in the hashtable.
package Dictionary;
import java.util.ArrayList;
import java.util.Hashtable;
import List.ListInterface;
import List.MyLinkedList;
public class MyHashtable implements DictionaryInterface {
protected int tableSize;
protected int size;
// The LinkedList is of type Entry
protected MyLinkedList[] table;
public MyHashtable(int tableSize) {
table = new MyLinkedList[tableSize];
this.tableSize = tableSize;
}
public int biggestBucket()
{
int biggestBucket = 0;
for(int i = 0; i < table.length; i++) {
// Loop through the table looking for non-null locations.
if (table[i] != null) {
// If you find a non-null location, compare the bucket size against the largest
// bucket size found so far. If the current bucket size is bigger, set biggestBucket
// to this new size.
MyLinkedList bucket = table[i];
if (biggestBucket < bucket.size())
biggestBucket = bucket.size();
}
}
return biggestBucket; // Return the size of the biggest bucket found.
}
// Returns the average bucket length. Gives a sense of how many collisions are happening overall.
public float averageBucket() {
float bucketCount = 0; // Number of buckets (non-null table locations)
float bucketSizeSum = 0; // Sum of the size of all buckets
for(int i = 0; i < table.length; i++) {
// Loop through the table
if (table[i] != null) {
// For a non-null location, increment the bucketCount and add to the bucketSizeSum
MyLinkedList bucket = table[i];
bucketSizeSum += bucket.size();
bucketCount++;
}
}
// Divide bucketSizeSum by the number of buckets to get an average bucket length.
return bucketSizeSum/bucketCount;
}
public String toString()
{
String s = "";
for(int tableIndex = 0; tableIndex < tableSize; tableIndex++) {
if (table[tableIndex] != null) {
MyLinkedList bucket = table[tableIndex];
for(int listIndex = 0; listIndex < bucket.size(); listIndex++) {
Entry e = (Entry)bucket.get(listIndex);
s = s + "key: " + e.key + ", value: " + e.value + "n";
}
}
}
return s;
}
protected class Entry
{
String key;
Object value;
Entry(String key, Object value) {
this.key = key;
this.value = value;
}
}
// Implement these methods
public boolean isEmpty() {return true;} // returns true if the Dictionary is empty, false otherwise.
public int size(){return -1;} //Returns the number of key/value pairs stored in the dictionary.
// Adds a value stored under the given key. If the key has already been stored in the Dictionary,
// replaces the value associated with the key and returns the old value. If the key isn't in the
dictionary
// returns null.
public Object put(String key, Object value){
// 1. Compute an array index given the key
// 2. If that location in the table is null,
// that means nothing has been previously stored using a key with this hash code.
// a. Create a new MyLinkedList to be the bucket.
// b. Add the new Entry for the key/value pair to the list.
// c. Set this location in the array equal to the new bucket (list).
// d. Increment the size (the number of unique keys you have stored).
// 3. If the location in the table isn't null,
// that means keys with this colliding hash code have been previously stored.
// 3a, a value exists for the key
// a. Linearly search through the bucket (the list) stored at this array
// location comparing the key for each entry with the key passed into put().
// If you get a match, this means this key as been previously stored.
// Save the old value in the Entry (so you can return it) and replace it with the new value.
// (use the code below)
// Entry oldValue = new Entry(key, e.value);
// e.value = value;
// NOTE: this is technically not correct as you would need to create a deep copy of the entry,
// however, that is outside the realm of this assignment. The code above will be
// enough to complete the assignment
// return old value here
// return oldValue.value;
// 3b, a value does not exist for the key
// b. If you don't find the key in the bucket,
// then just add a new Entry (with the key and value) to the beginning of the list.
// Increment the size.
return null;
}
public Object get(String key){
// 1. Compute an array index given the key
// 2. If that location in the table is null,
// that means nothing has been stored using a key with this hash code.
// So we can return null.
// 4. Linearly search through the bucket (the list),
// comparing the key for each entry with the key passed into get().
// Extracting each element in
// the Linked List
// If you find a match, return the value.
return null;
} // Retrieves the value stored with the key.
public void remove(String key){
// 1. Compute an array index given the key
// 2. If that location in the table is null, then this key has definitely not been used to store a value.
// 3. If the location in the table has a bucket,
// we need to linearly search it to see if it contains an Entry with the key.
// If you find an Entry in the bucket (linked list) with the key:
// a. Remove this Entry from the bucket.
// b. Decrement size (the number of unique keys stored in the hashtable).
} // Deletes the key/value pair stored with the given key.
public void clear(){} // Empties the dictionary.
public String[] getKeys(){
// 1. Create a String[] with a size equal to the number of unique keys in the hashtable
// 2. Iterate through the hashtable array.
// For each table location that isn't null
// a. Iterate though the bucket (linked list)
// getting the key out of each Entry and storing it in
// the array of strings you created in step 1.
// 3. Return the String[]
return null;
}
}

More Related Content

Similar to Assignment4 Assignment 4 Hashtables In this assignment we w.pdf

Sienna 9 hashing
Sienna 9 hashingSienna 9 hashing
Sienna 9 hashing
chidabdu
 
Generics Collections
Generics CollectionsGenerics Collections
Generics Collections
phanleson
 
Concurrent Hashing and Natural Parallelism : The Art of Multiprocessor Progra...
Concurrent Hashing and Natural Parallelism : The Art of Multiprocessor Progra...Concurrent Hashing and Natural Parallelism : The Art of Multiprocessor Progra...
Concurrent Hashing and Natural Parallelism : The Art of Multiprocessor Progra...
Subhajit Sahu
 
java I am trying to run my code but it is not letting me .pdf
java    I am trying to run my code but it is not letting me .pdfjava    I am trying to run my code but it is not letting me .pdf
java I am trying to run my code but it is not letting me .pdf
adinathassociates
 

Similar to Assignment4 Assignment 4 Hashtables In this assignment we w.pdf (20)

Data Structures Design Notes.pdf
Data Structures Design Notes.pdfData Structures Design Notes.pdf
Data Structures Design Notes.pdf
 
Hashing
HashingHashing
Hashing
 
VCE Unit 04vv.pptx
VCE Unit 04vv.pptxVCE Unit 04vv.pptx
VCE Unit 04vv.pptx
 
Collections Api - Java
Collections Api - JavaCollections Api - Java
Collections Api - Java
 
Sienna 9 hashing
Sienna 9 hashingSienna 9 hashing
Sienna 9 hashing
 
hashing.pdf
hashing.pdfhashing.pdf
hashing.pdf
 
Generics Collections
Generics CollectionsGenerics Collections
Generics Collections
 
Concurrent Hashing and Natural Parallelism : The Art of Multiprocessor Progra...
Concurrent Hashing and Natural Parallelism : The Art of Multiprocessor Progra...Concurrent Hashing and Natural Parallelism : The Art of Multiprocessor Progra...
Concurrent Hashing and Natural Parallelism : The Art of Multiprocessor Progra...
 
linear probing
linear probinglinear probing
linear probing
 
Algorithms notes tutorials duniya
Algorithms notes   tutorials duniyaAlgorithms notes   tutorials duniya
Algorithms notes tutorials duniya
 
java I am trying to run my code but it is not letting me .pdf
java    I am trying to run my code but it is not letting me .pdfjava    I am trying to run my code but it is not letting me .pdf
java I am trying to run my code but it is not letting me .pdf
 
Generics collections
Generics collectionsGenerics collections
Generics collections
 
Presentation.pptx
Presentation.pptxPresentation.pptx
Presentation.pptx
 
DS THEORY 35.pptx
DS THEORY 35.pptxDS THEORY 35.pptx
DS THEORY 35.pptx
 
18 hashing
18 hashing18 hashing
18 hashing
 
data structures and algorithms Unit 3
data structures and algorithms Unit 3data structures and algorithms Unit 3
data structures and algorithms Unit 3
 
Collections
CollectionsCollections
Collections
 
Array list(1)
Array list(1)Array list(1)
Array list(1)
 
Java Collections Framework
Java Collections FrameworkJava Collections Framework
Java Collections Framework
 
11_hashtable-1.ppt. Data structure algorithm
11_hashtable-1.ppt. Data structure algorithm11_hashtable-1.ppt. Data structure algorithm
11_hashtable-1.ppt. Data structure algorithm
 

More from kksrivastava1

Assignment Overview Over twothirds of Americans are conside.pdf
Assignment Overview Over twothirds of Americans are conside.pdfAssignment Overview Over twothirds of Americans are conside.pdf
Assignment Overview Over twothirds of Americans are conside.pdf
kksrivastava1
 
Assignment is a case essay and requires you to obtain suffic.pdf
Assignment is a case essay and requires you to obtain suffic.pdfAssignment is a case essay and requires you to obtain suffic.pdf
Assignment is a case essay and requires you to obtain suffic.pdf
kksrivastava1
 

More from kksrivastava1 (20)

Assume that there exists a bestfirst search algorithm in wh.pdf
Assume that there exists a bestfirst search algorithm in wh.pdfAssume that there exists a bestfirst search algorithm in wh.pdf
Assume that there exists a bestfirst search algorithm in wh.pdf
 
Assume that there are 5 processes P0 through P4 and 4 type.pdf
Assume that there are 5 processes P0 through P4 and 4 type.pdfAssume that there are 5 processes P0 through P4 and 4 type.pdf
Assume that there are 5 processes P0 through P4 and 4 type.pdf
 
Assume that there are 5 processes PO through P4 and 4 type.pdf
Assume that there are 5 processes PO through P4 and 4 type.pdfAssume that there are 5 processes PO through P4 and 4 type.pdf
Assume that there are 5 processes PO through P4 and 4 type.pdf
 
Assume that SLL is a singly linked list with the head node .pdf
Assume that SLL is a singly linked list with the head node .pdfAssume that SLL is a singly linked list with the head node .pdf
Assume that SLL is a singly linked list with the head node .pdf
 
Assume that i is in t0 register x is in f0 register the .pdf
Assume that i is in t0 register x is in f0 register the .pdfAssume that i is in t0 register x is in f0 register the .pdf
Assume that i is in t0 register x is in f0 register the .pdf
 
Assume that a simple random sample has been selected and tes.pdf
Assume that a simple random sample has been selected and tes.pdfAssume that a simple random sample has been selected and tes.pdf
Assume that a simple random sample has been selected and tes.pdf
 
Assume that a security model is needed to protect informatio.pdf
Assume that a security model is needed to protect informatio.pdfAssume that a security model is needed to protect informatio.pdf
Assume that a security model is needed to protect informatio.pdf
 
Assume that 352 of people have sleepwalked Assume that in.pdf
Assume that 352 of people have sleepwalked Assume that in.pdfAssume that 352 of people have sleepwalked Assume that in.pdf
Assume that 352 of people have sleepwalked Assume that in.pdf
 
assume Assume fn4n01gn10lognhn2npn3logn i.pdf
assume Assume fn4n01gn10lognhn2npn3logn i.pdfassume Assume fn4n01gn10lognhn2npn3logn i.pdf
assume Assume fn4n01gn10lognhn2npn3logn i.pdf
 
Assume an organization is planning to move a significant IT .pdf
Assume an organization is planning to move a significant IT .pdfAssume an organization is planning to move a significant IT .pdf
Assume an organization is planning to move a significant IT .pdf
 
Assume a singly linkedlist List class of nodes sorted by .pdf
Assume a singly linkedlist List class of nodes sorted by .pdfAssume a singly linkedlist List class of nodes sorted by .pdf
Assume a singly linkedlist List class of nodes sorted by .pdf
 
Assume a firm has earnings before depreciation and taxes of .pdf
Assume a firm has earnings before depreciation and taxes of .pdfAssume a firm has earnings before depreciation and taxes of .pdf
Assume a firm has earnings before depreciation and taxes of .pdf
 
Assignment Overview Over twothirds of Americans are conside.pdf
Assignment Overview Over twothirds of Americans are conside.pdfAssignment Overview Over twothirds of Americans are conside.pdf
Assignment Overview Over twothirds of Americans are conside.pdf
 
Associativity Left to right 1 Show the order of evaluatio.pdf
Associativity Left to right 1 Show the order of evaluatio.pdfAssociativity Left to right 1 Show the order of evaluatio.pdf
Associativity Left to right 1 Show the order of evaluatio.pdf
 
ASSIGNMENT OI a The IASBs Framework for the Preparation a.pdf
ASSIGNMENT OI a The IASBs Framework for the Preparation a.pdfASSIGNMENT OI a The IASBs Framework for the Preparation a.pdf
ASSIGNMENT OI a The IASBs Framework for the Preparation a.pdf
 
Assignment is a case essay and requires you to obtain suffic.pdf
Assignment is a case essay and requires you to obtain suffic.pdfAssignment is a case essay and requires you to obtain suffic.pdf
Assignment is a case essay and requires you to obtain suffic.pdf
 
Assignment 4 Class Petromyzontida 10 List three features o.pdf
Assignment 4 Class Petromyzontida 10 List three features o.pdfAssignment 4 Class Petromyzontida 10 List three features o.pdf
Assignment 4 Class Petromyzontida 10 List three features o.pdf
 
Assign the ICD10CM codes to diagnosis and conditions and.pdf
Assign the ICD10CM codes to diagnosis and conditions and.pdfAssign the ICD10CM codes to diagnosis and conditions and.pdf
Assign the ICD10CM codes to diagnosis and conditions and.pdf
 
Assigned Topic Alzheimers disease Case study Create a b.pdf
Assigned Topic Alzheimers disease Case study  Create a b.pdfAssigned Topic Alzheimers disease Case study  Create a b.pdf
Assigned Topic Alzheimers disease Case study Create a b.pdf
 
Assignment Instructions Answer the below questions Please .pdf
Assignment Instructions Answer the below questions Please .pdfAssignment Instructions Answer the below questions Please .pdf
Assignment Instructions Answer the below questions Please .pdf
 

Recently uploaded

Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Krashi Coaching
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
ciinovamais
 

Recently uploaded (20)

Measures of Dispersion and Variability: Range, QD, AD and SD
Measures of Dispersion and Variability: Range, QD, AD and SDMeasures of Dispersion and Variability: Range, QD, AD and SD
Measures of Dispersion and Variability: Range, QD, AD and SD
 
Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)
 
Accessible design: Minimum effort, maximum impact
Accessible design: Minimum effort, maximum impactAccessible design: Minimum effort, maximum impact
Accessible design: Minimum effort, maximum impact
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introduction
 
APM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAPM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across Sectors
 
Arihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdfArihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdf
 
General AI for Medical Educators April 2024
General AI for Medical Educators April 2024General AI for Medical Educators April 2024
General AI for Medical Educators April 2024
 
Paris 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activityParis 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activity
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
 
fourth grading exam for kindergarten in writing
fourth grading exam for kindergarten in writingfourth grading exam for kindergarten in writing
fourth grading exam for kindergarten in writing
 
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
Explore beautiful and ugly buildings. Mathematics helps us create beautiful d...
 
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
 
Key note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdfKey note speaker Neum_Admir Softic_ENG.pdf
Key note speaker Neum_Admir Softic_ENG.pdf
 
Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1
 
social pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajansocial pharmacy d-pharm 1st year by Pragati K. Mahajan
social pharmacy d-pharm 1st year by Pragati K. Mahajan
 
Activity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdfActivity 01 - Artificial Culture (1).pdf
Activity 01 - Artificial Culture (1).pdf
 
Introduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The BasicsIntroduction to Nonprofit Accounting: The Basics
Introduction to Nonprofit Accounting: The Basics
 
The Most Excellent Way | 1 Corinthians 13
The Most Excellent Way | 1 Corinthians 13The Most Excellent Way | 1 Corinthians 13
The Most Excellent Way | 1 Corinthians 13
 
A Critique of the Proposed National Education Policy Reform
A Critique of the Proposed National Education Policy ReformA Critique of the Proposed National Education Policy Reform
A Critique of the Proposed National Education Policy Reform
 
Student login on Anyboli platform.helpin
Student login on Anyboli platform.helpinStudent login on Anyboli platform.helpin
Student login on Anyboli platform.helpin
 

Assignment4 Assignment 4 Hashtables In this assignment we w.pdf

  • 1. Assignment4 Assignment 4: Hashtables In this assignment we will use a rhyming dictionary and loading it into a hashtable and using the hashtable ADT(abstract data type) to implement a bad poetry generator. Objectives TODO #1: Implement a hashtable TODO #2: Loading the dictionary Optional: TODO #3: Removing unrhymable words Testing Testing can be done through Maven with the command, mvn test To run more specific tests, run the command mvn -Dtest=AssignmentTest#TESTCASEHERE test where TESTCASEHERE is the test case you want to run. These test cases can be found in src/test/java/AssignmentTest Ex: mvn -Dtest=AssignmentTest#test_2_puts test The results can be found in the command line or in target/surefire-reports/AssignmentTest.txt after execution. Part of grading will be these test cases. Alternatively, You can use the main method found in RhymingDict.java. In fact, the test cases are dervied from that main method. To Do 1: Implementing a Hashtable Youll be implementing a hashtable class called MyHashtable. It implements the interface DictionaryInterface. The hashtable youll be making will use Strings as the keys and Object as the values. Similar to linked lists, by storing Object as values, you can store any kind of object in the hashtable. To implement a hashtable: Use a protected inner class inside MyHashtable called Entry. This inner class stores Key/Value pairs. So it has two fields: String key Object value It also should have a constructor for initializing the key and value. Your hashtable will define three protected fields (remember that protected means that the field can only be accessed from within the class or by any child class of the class). int tableSize - the size of the array being used by the hashtable int size- the number of key/value entries stored in the hashtable MyLinkedList[] table - an array of MyLinkedList. The reason that each element of the array is a linked list is to store multiple entries which collide, that is, for which the hash for the different keys is the same index in the table. Youll be implementing the following methods on MyHashtable
  • 2. public boolean isEmpty() Returns true if the hashtable is empty, false otherwise. You can use the size field to determine this easily. public int size() Returns the size (number of key/value pairs stored in the hashtable). Theres more info about how to implement this method below. public Object put(String key, Object value) Adds a new key/value pair to the hashtable. If the key has been previously added, it replaces the value stored with this key with the new value, and returns the old value. Otherwise it returns null. public Object get(String key) Returns the value stored with the key. If the key has not previously been stored in the hashtable, returns null. Theres more info about how to implement this method below. public void remove(String key) Removes the key/value pair associated with the key from the hashtable. Theres more info about how to implement this method below. public void clear() Empties the hashtable. The easiest way to do this is to just set table equal to a new fresh array - the old one will be garbage collected (memory reclaimed) by java. Remember to set size to 0 as well. public String[] getKeys() Returns an array of all the keys stored in the table. This function is necessary because having all the keys is the only way to iterate through the values in a hashtable. Theres more info about how to implement this method below. public MyHashtable(int tableSize) The constructor for the hashtable. Takes an argument that is used to set the size of the array used to store the hashtable. Initialize tableSize, table, and size. Hash Codes In a hashtable, to compute an index into the array given a key you compute a hashcode for the key. Since our keys are all Strings, well be using the method hashCode() which is already provided on Strings. As an example: The integer returned by hashCode() ranges over the full range of negative and positive integers. So the number could be way out of range for indexing our table (depending on our array size) or could be negative, which we definitely cant use for indexing our array. So well use the same trick we talked about with array-based Queues of using the modulo operator to get the number within range: Math.abs() gets the absolute value (to get rid of negative numbers) and % tableSize puts the number into the range 0..tableSize-1 by returning the remainder after dividing by tableSize. get(), put() and remove() all take a key as one of the arguments. So these functions will all need to compute an array index from the key to look in the table. Remember that our table is an array of type MyLinkedList, where each item in the linked list is an Entry (storing a key and value). Why cant we just store the values directly in the table? The reason is that hash functions can result in collisions, where two different keys get mapped to the same array index (because they have the same hash code). So we have to story our entries(key/value pairs) in lists. In a hashtable, this list is called a bucket (or sometimes a slot). Each list in the table stores entries whose keys result in hash collisions. But if our hash function is good, it will spread the data out
  • 3. well so that no bucket ever gets too long. Implementing Object get(String key) To implement Object get(String key)you need to: Compute an array index given the key (see above). If that location in the table is null, that means nothing has been stored using a key with this hash code. So we can return null. If the location isnt null, then it contains a MyLinkedList which is the bucket for all keys that collide using the hash function. Linearly search through the bucket (the list), comparing the key for each entry with the key passed into get(). If you find a match, return the value. If you get to the end of the list without finding a match, return null (nothing stored for this key). Implementing Object put(String key, Object value) To implement Object put(String key, Object value)you need to: Compute an array index given the key. If that location in the table is null, that means nothing has been previously stored using a key with this hash code. a. Create a new MyLinkedList to be the bucket. b. Add the new Entry for the key/value pair to the list. c. Set this location in the array equal to the new bucket (list). d. Increment the size (the number of unique keys you have stored). If the location in the table isnt null, that means keys with this colliding hash code have been previously stored. So our new key/value pair might be a key thats already been added (in which case we replace the value), or a brand new key (in which case we add a new Entry to the bucket). a. Linearly search through the bucket (the list) stored at this array location comparing the key for each entry with the key passed into put(). If you get a match, this means this key as been previously stored. Save the old value in the Entry (so you can return it) and replace it with the new value. You dont need to increment the size since youre not adding a new key. b. If you dont find the key in the bucket, then just add a new Entry (with the key and value) to the beginning of the list. Increment the size. Return the old value if storing using an existing key (step 3.a above), otherwise return null if youre adding a new key (step 2 or step 3.b). Implementing void remove(String key) To implement void remove(String key) you need to: Compute an array index given the key. If that location in the table is null, then this key has definitely not been used to store a value. No need to do anything. If the location in the table has a bucket, we need to linearly search it to see if it contains an Entry with the key. If you find an Entry in the bucket (linked list) with the key: a. Remove this Entry from the bucket. b. Decrement size (the number of unique keys stored in the hashtable). Implementing String[] getKeys() To implement String[] getKeys() you need to:
  • 4. Create a String[] with a size equal to the number of unique keys in the hashtable (hint: one of our hashtable fields is keeping track of this). Iterate through the hashtable array. For each table location that isnt null: a. Iterate through the bucket (linked list), getting the key out of each Entry and storing it in the array of strings you created in step 1. Youll need some kind of counter to keep track of where in the array of Strings youre adding the key. Return the String[] Extra Functions for Experimentation Two extra functions that are not part of the DictionaryInterface have been provided on MyHashtable to let you experiment with how collisions change as you change the table size of MyHashtable. Theres no To Do item associated with these functions; theyre just for your own experimentation. public int biggestBucket()java returns the size of the largest bucket (the most collisions) in the hashtable. public float averageBucket() returns the average bucket size. Together, these two functions give you a sense of how frequently collisions are happening in the hashtable. As you make the table size smaller, the number of collisions will go up. In the limit of creating a hashtable with 1 table entry, then every key/value pair is stored in one big list. On MyHashtable theres also an implementation of public String toString(). This allows you to print out the key/value pairs in your hashtable. Theres also a method in RhymingDict.java called public void testDictionary(DictionaryInterface dict). You can use this method to test your hashtable once youve implemented it. It does some simple adding, removing and replacing of key/value pairs and prints out the hashtable so you can confirm your table is working correctly. Rhyming Dict After youve made your hashtable, the remaining two To Do items are in RhymingDict.java. RhymingDict.java already does the following: Creates a MyHashTable with size 20,000. The keys well use in this hashtable are rhyming groups (like AA1 V AH0). The values well use in this hashtable are MySortedLinkedList. Each MySortedLinkedListwill store individual words sharing a rhyme group. Were providing you with a working version of MySortedLinkedList. Does the file management to read each line from the CMU Pronunciation dictionary The CMU Pronunciation dictionary is a free data source of how each word in English is pronounced, useful for text-to-speech or rhyming applications. Writes poems Picks two rhyming groups at random from an array of keys. Gets the MySortedLinkedList of words for each group. Picks two random indices for each list (based on the length of the list), and uses these two get four words, two words from each list. Uses those words to make a poem, e.g. Note: we removed most of the bad words from the dictionary, but the poems might still sometimes make bad or offensive juxtapositions
  • 5. You need to implement the following: TO DO # 2: Store each line from the CMU dictionary in the hashtable. This involves implementing the method storeRhyme(). Use getWord() and getRhymeGroup() to get the word and rhyme group for the line. Lookup (get) the key (the rhyme group) in the Dictionary (hashtable). If the result is null, then this rhyme group has not been added before. Create a new MySortedLinkedList. Add the word to the list. Put the key (rhyme group) and value (list) in the Dictionary. If the result of the lookup (get) isnt null, then weve already started a word list for this rhyme group. Add the word to the list returned by get(). Nothing needs to be added to the Dictionary since the list is already in the Dictionary. (Optional) TO DO #3: Remove the unrhymable words from the dictionary. Some words are in a rhyme group by themselves. That means that nothing rhymes with them. We want to get rid of those before trying to make poems. Youll do this by implementing removeUnrhymables(). Use getKeys() to get an array of all the keys. Iterate through all the keys, retrieving the value (linked list) associated with each key. If the length of the list is 1, that means theres only one word in the list: nothing rhymes with it. Use Dictionary.remove() to remove this entry. If youre curious to see what words dont have rhymes (at least according to the CMU pronunciation dictionary), you could add a println to print out the words as you remove their corresponding entries. If you do this, dont forget to comment it out before you turn it in. Example Input and Output RhymingDict can take 0, 1 or 2 command line arguments. The first argument is a seed for the random number generator. If you provide 0 arguments this defaults to the current system time. The second argument is the number of poems to generate. If 0 or 1 arguments are provided, this defaults to 3. For this command line: the output should look like: Complete code in Java The hashtable you'll be making will use Strings as the keys and Object as the values. Similar to linked lists, by storing Object as values, you can store any kind of object in the hashtable. package Dictionary; import java.util.ArrayList; import java.util.Hashtable; import List.ListInterface; import List.MyLinkedList; public class MyHashtable implements DictionaryInterface { protected int tableSize; protected int size;
  • 6. // The LinkedList is of type Entry protected MyLinkedList[] table; public MyHashtable(int tableSize) { table = new MyLinkedList[tableSize]; this.tableSize = tableSize; } public int biggestBucket() { int biggestBucket = 0; for(int i = 0; i < table.length; i++) { // Loop through the table looking for non-null locations. if (table[i] != null) { // If you find a non-null location, compare the bucket size against the largest // bucket size found so far. If the current bucket size is bigger, set biggestBucket // to this new size. MyLinkedList bucket = table[i]; if (biggestBucket < bucket.size()) biggestBucket = bucket.size(); } } return biggestBucket; // Return the size of the biggest bucket found. } // Returns the average bucket length. Gives a sense of how many collisions are happening overall. public float averageBucket() { float bucketCount = 0; // Number of buckets (non-null table locations) float bucketSizeSum = 0; // Sum of the size of all buckets for(int i = 0; i < table.length; i++) { // Loop through the table if (table[i] != null) { // For a non-null location, increment the bucketCount and add to the bucketSizeSum MyLinkedList bucket = table[i]; bucketSizeSum += bucket.size(); bucketCount++; } } // Divide bucketSizeSum by the number of buckets to get an average bucket length. return bucketSizeSum/bucketCount; } public String toString() { String s = ""; for(int tableIndex = 0; tableIndex < tableSize; tableIndex++) {
  • 7. if (table[tableIndex] != null) { MyLinkedList bucket = table[tableIndex]; for(int listIndex = 0; listIndex < bucket.size(); listIndex++) { Entry e = (Entry)bucket.get(listIndex); s = s + "key: " + e.key + ", value: " + e.value + "n"; } } } return s; } protected class Entry { String key; Object value; Entry(String key, Object value) { this.key = key; this.value = value; } } // Implement these methods public boolean isEmpty() {return true;} // returns true if the Dictionary is empty, false otherwise. public int size(){return -1;} //Returns the number of key/value pairs stored in the dictionary. // Adds a value stored under the given key. If the key has already been stored in the Dictionary, // replaces the value associated with the key and returns the old value. If the key isn't in the dictionary // returns null. public Object put(String key, Object value){ // 1. Compute an array index given the key // 2. If that location in the table is null, // that means nothing has been previously stored using a key with this hash code. // a. Create a new MyLinkedList to be the bucket. // b. Add the new Entry for the key/value pair to the list. // c. Set this location in the array equal to the new bucket (list). // d. Increment the size (the number of unique keys you have stored). // 3. If the location in the table isn't null, // that means keys with this colliding hash code have been previously stored. // 3a, a value exists for the key // a. Linearly search through the bucket (the list) stored at this array // location comparing the key for each entry with the key passed into put(). // If you get a match, this means this key as been previously stored. // Save the old value in the Entry (so you can return it) and replace it with the new value. // (use the code below)
  • 8. // Entry oldValue = new Entry(key, e.value); // e.value = value; // NOTE: this is technically not correct as you would need to create a deep copy of the entry, // however, that is outside the realm of this assignment. The code above will be // enough to complete the assignment // return old value here // return oldValue.value; // 3b, a value does not exist for the key // b. If you don't find the key in the bucket, // then just add a new Entry (with the key and value) to the beginning of the list. // Increment the size. return null; } public Object get(String key){ // 1. Compute an array index given the key // 2. If that location in the table is null, // that means nothing has been stored using a key with this hash code. // So we can return null. // 4. Linearly search through the bucket (the list), // comparing the key for each entry with the key passed into get(). // Extracting each element in // the Linked List // If you find a match, return the value. return null; } // Retrieves the value stored with the key. public void remove(String key){ // 1. Compute an array index given the key // 2. If that location in the table is null, then this key has definitely not been used to store a value. // 3. If the location in the table has a bucket, // we need to linearly search it to see if it contains an Entry with the key. // If you find an Entry in the bucket (linked list) with the key: // a. Remove this Entry from the bucket. // b. Decrement size (the number of unique keys stored in the hashtable). } // Deletes the key/value pair stored with the given key. public void clear(){} // Empties the dictionary. public String[] getKeys(){ // 1. Create a String[] with a size equal to the number of unique keys in the hashtable // 2. Iterate through the hashtable array. // For each table location that isn't null // a. Iterate though the bucket (linked list) // getting the key out of each Entry and storing it in // the array of strings you created in step 1.
  • 9. // 3. Return the String[] return null; } }