//Hash.h
// A HashTable f holds a set of(key, value) associations, just like an AssocList,
// except all operations are O(1) (provided the hashing is good)
//
// basic operations are:
//
// f[key] = value -- assign a value associated with key
// value = f[key] -- retrieve the value associated with key.
// If there was no association, allocate a new association
// with the value optionally set to some default.
//
// f.exists(key) -- does key have a value associated with it?
// f.remove(key) -- remove the association for key (if one exists)
//
// f.clear() -- remove all associations
//
// f.keys() -- return array of existing keys
// f.values() -- return array of existing values
//
// also: copy constructor, operator=, operator<<
//
// use like this:
//
// #include "Hash.h"
// #include "Hash.cc"
//
// ...
//
// HashTable<char *, int> h(-1); // with default initialization value
// HashTable<char *, int> g; // without default initialization value
//
// h["hi"] = 3;
//
// Array<char *> keys = h.keys();
//
// for (int i = 0; i < keys.size(); ++i)
// cout << h[keys[i]] << endl;
//
// Array<int> keys = h.values();
//
// h.remove("hi");
//
// h.clear();
//
// if (h.exists("hi")) ... // test if "hi" is a key without creating an entry for it
//
// g = h; // deep copy by operator=
//
//
#ifndef _HASH_H
#define _HASH_H
#include <iostream.h>
#include "Array.h"
#include "AssocList.h"
template <class KEY, class VALUE>
class HashTable {
public:
//destructor
~HashTable();
// constructors
HashTable();
HashTable(VALUE const & def);
HashTable(HashTable const & a);
// operator= by deep copy
HashTable& operator=(HashTable const & a);
// clear
void clear();
// exists
int exists(KEY const & k) const;
// remove
void remove(KEY const & k);
// operator[] and operator[] const
VALUE & operator[](KEY const & k);
VALUE operator[](KEY const & k) const;
// keys() and values()
Array<KEY> keys() const;
Array<VALUE> values() const;
// output
friend ostream & operator<< <>(ostream &, const HashTable<KEY,VALUE> &);
private:
unsigned int n_keys;
unsigned int hash_modulus;
Array<AssocList<KEY,VALUE> > buckets;
int hash(KEY const & k) const;
int use_default;
VALUE default_init;
void grow();
};
// default hash function
template <typename T>
int Hash(T const &s) {
return (int) s;
}
// specialization for char *'s
template <>
int Hash(char * const & a) {
char *s = a;
int hash = 0;
do hash += *s; while (*s++);
return hash;
}
#endif