#include <iostream> #include <vector> using namespace std; bool isPrime(int x) { for(int i = 2; i * i <= x; ++i) { if(x % i == 0) return false; } return true; } int nextprime(int x) { for(;;++x) { if(isPrime(x)) return x; } } template<class HashedObj> class HashTable { public: explicit HashTable(int size = 101); bool contains(const HashedObj& x) const; void makeEmpty(); bool insert(const HashedObj& x); bool remove(const HashedObj& x); enum EntryType{ACTIVE, EMPTY, DELETED}; void printhash() const; private: struct HashEnty { HashedObj element; EntryType info; HashEnty(const HashedObj &e = HashedObj(), EntryType i = EMPTY) : element(e), info(i){} }; vector<HashEnty> array; int currentSize; bool isActive(int currentPos) const; int findPos(const HashedObj& x) const; void rehash(); int myhash(const HashedObj& x) const; int hash(const int& x) const; int hash(const string& x) const; }; template<class HashedObj> HashTable<HashedObj>::HashTable(int size) : array(nextprime(size)) { makeEmpty(); } template<class HashedObj> bool HashTable<HashedObj>::contains(const HashedObj& x) const { return isActive(findPos(x)); } template<class HashedObj> void HashTable<HashedObj>::makeEmpty() { currentSize = 0; for(size_t i = 0; i < array.size(); ++i) array[i].info = EMPTY; } template<class HashedObj> bool HashTable<HashedObj>::insert(const HashedObj& x) { int currentPos = findPos(x); if(isActive(currentPos)) return false; array[currentPos] = HashEnty(x, ACTIVE); if(++currentSize > array.size() / 2) rehash(); return true; } template<class HashedObj> bool HashTable<HashedObj>::remove(const HashedObj& x) { int currentPos = findPos(x); if(!isActive(currentPos)) return false; array[currentPos].info = DELETED; return true; } template<class HashedObj> bool HashTable<HashedObj>::isActive(int currentPos) const { return array[currentPos].info == ACTIVE; } template<class HashedObj> int HashTable<HashedObj>::findPos(const HashedObj& x) const { int offset = 1; int currentPos = myhash(x); while(array[currentPos].info != EMPTY && array[currentPos].element != x) { currentPos += offset; offset += 2; if(currentPos >= array.size()) currentPos -= array.size(); } return currentPos; } template<class HashedObj> void HashTable<HashedObj>::rehash() { vector<HashEnty> oldArray = array; array.resize(nextprime(2 * oldArray.size())); for(size_t i = 0; i < array.size(); ++i) array[i].info = EMPTY; currentSize = 0; for(size_t i = 0; i < oldArray.size(); ++i) if(oldArray[i].info == ACTIVE) insert(oldArray[i].element); } template<class HashedObj> int HashTable<HashedObj>::myhash(const HashedObj& x) const { int cnt = 0; int hashVal = hash(x); while(isActive(hashVal)) hashVal = (hash(x) + (++cnt)) % array.size(); return hashVal; } template<> int HashTable<int>::hash(const int& x) const { int hashVal = x % array.size(); if(hashVal < 0) hashVal += array.size(); return hashVal; } template<> int HashTable<string>::hash(const string& x) const { int hashVal = 0; for(size_t i = 0; i < x.length(); ++i) hashVal = 37 * hashVal + x[i]; hashVal %= array.size(); if(hashVal < 0) hashVal += array.size(); return hashVal; } template<class HashedObj> void HashTable<HashedObj>::printhash() const { for(size_t i = 0; i != array.size(); ++i) cout << array[i].element << " "; } int main() { return 0; }