// StringDictionary.cc // A hash table mapping Strings to instances of the Record class that holds // the associated data. You need to fill in the methods for this part. // Since the keys are all character strings of a given length, matchlength, // but raw character strings are passed in where only the first matchlength // characters are really the key, the match length is a parameter to the // constructor and stored as an instance variable so we don't have to keep // figuring it out on each call. #include #include "math.h" #include "StringDictionary.h" #include "Record.h" using namespace std; // fill in your instance variables and any constants. Also add any private // methods that you'd like DictionaryRecord* DELETED = new DictionaryRecord("a",NULL); //sentinel for deleted // // Create an empty table big enough to hold maxSize records with // the desired load ratio maintained // StringDictionary::StringDictionary(int maxSize,int imatchLength){ matchLength = imatchLength; // you fill in the rest } // Private Method to compate two strings. It returns true if they // are equal and false otherwise. bool StringDictionary::equals(const char* key1, const char* key2){ bool equal = true; for (int j = 0; j < matchLength; j++){ if (key1[j] != key2[j]) equal=false; } return equal; } // // Associates the specified record r with the given key in the // dictionary. If the dictionary already contains a record for // this key, the old record is replaced by r. The function returns // a pointer to the Record previously associated with the specified // key, or null if there was no mapping for the key. A null return // can also indicate that the map previously associated null with // the specified key Record* StringDictionary::put(const char* key, Record *r){ // you fill in the rest } // Returns a boolean that is true if the gien key is contained in // the dictionary. If the key is not in use, false is returned. bool StringDictionary::contains(const char* key){ // you fill in the rest } // // Returns a pointer to the Record associated with the specified key // Returns null if the dictionary does not contain any item with the // given key. A return value of null does not necessarily indicate // that the dictionary does not contain the key; it's also possible that // the map explicitly maps the key to null. The containsKey method may // be used to distinguish between these two cases. Record* StringDictionary::get(const char* key){ // you fill in the rest } // // Removes the given key from the dictionary, if it is present. // Returns the Record associated with the key if it was in use. or // NULL if the key was not in the dictionary. (A NULL return can also // indicate that the Record previously associated with the specified // key was NULL.) Record* StringDictionary::remove(const char* key){ // you fill in the rest } // Returns the number of keys stored in the Dictionary int StringDictionary::size(){ // you fill in the rest } ////////////////////////////////////////////////////////// // Convert a string key into an integer that serves as input to hash // functions. This mapping is based on the idea of a linear-congruential // pesudorandom number generator, in which successive values r_i are // generated by computing // r_i = ( A * r_(i-1) + B ) mod M // A is a large prime number, while B is a small increment thrown in // so that we don't just compute successive powers of A mod M. // // We modify the above generator by perturbing each r_i, adding in // the ith character of the string and its offset, to alter the // pseudorandom sequence. // int StringDictionary::toHashKey(const char *s){ int A = 1952786893; int B = 367253; int v = B; for (int j = 0; j < matchLength; j++) v = A * (v + int(s[j]) + j) + B; if (v < 0) v = -v; return v; } // // Primary hash function using the multiplication method // int StringDictionary::baseHash(int hashKey){ double a = .618; double frac = (hashKey * a) - (int)(hashKey * a); // computs hashKey*a - floor(k*a) int hashValue = (int) (tableSize * frac); // Keeps most two sig. digits return hashValue; // of frac to return } // // Secondary hash function. To be sure that all table entries are visited, // this requrires that the tableSize is a power of 2. Since the value // returned is guaranteed to be odd, this ensures that the step size and the // table size are relatively prime. int StringDictionary::stepHash(int hashKey){ int step = (hashKey % (tableSize -1)); if (step % 2 == 0) return step+1; else return step; }