Skip to content

Instantly share code, notes, and snippets.

@jagt
Last active December 18, 2015 13:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jagt/5791219 to your computer and use it in GitHub Desktop.
Save jagt/5791219 to your computer and use it in GitHub Desktop.
stupid c++ hash map implementation
#include <cstddef>
#include <iostream>
#include <string>
#include <functional>
#include <cassert>
using namespace std;
template<class T>
class HashMap
{
private:
struct Pair
{
string key;
T value;
Pair *next;
};
Pair **buckets;
size_t capacity;
// need -std=c++11 in gcc, but VS9 has this
static hash<string> str_hash;
size_t hash_string(const string &s)
{
size_t t = str_hash(s) % capacity;
return t;
}
Pair* get(const string& key)
{
Pair *p = buckets[hash_string(key)];
while (p)
{
if (p->key == key)
{
return p;
}
else
{
p = p->next;
}
}
return NULL;
}
public:
HashMap(int capacity)
{
this->capacity = capacity;
buckets = new Pair*[capacity](); // add () to initialize to 0 in a super subtle way
}
~HashMap()
{
delete [] buckets;
}
void add(string key, const T &value)
{
Pair *newpair = new Pair();
newpair->key = key;
newpair->value = value;
size_t keyhash = hash_string(key);
Pair *p = buckets[keyhash];
if (!p)
{
buckets[keyhash] = newpair;
}
else
{
while (p->next) p = p->next;
p->next = newpair;
}
}
bool remove(const string& key)
{
Pair *p = get(key);
if (!p) return false;
size_t keyhash = hash_string(key);
Pair *prev = buckets[keyhash];
if (prev == p)
{
buckets[keyhash] = NULL;
}
else
{
while(prev->next != p) prev = prev->next;
prev->next = NULL;
}
delete p;
return true;
}
bool contains(const string& key)
{
return get(key) != NULL;
}
// handles both add and get
T& operator [] (const string& key)
{
Pair *p = get(key);
if (!p)
{
T t;
add(key, t);
}
return get(key)->value;
}
void clear()
{
for (size_t ix = 0; ix < capacity; ++ix)
{
Pair *p = buckets[ix];
while (p)
{
Pair *dead = p;
p = p->next;
delete dead;
}
buckets[ix] = NULL;
}
}
};
template<class T>
hash<string> HashMap<T>::str_hash = hash<string>();
int main()
{
HashMap<string> ssmap(3);
ssmap.add("key", "blooooooop");
const string &s = ssmap["key"];
ssmap["key"] = "blah";
assert(ssmap.contains("key"));
assert(ssmap["key"] == "blah");
assert(s == "blah");
assert(ssmap.remove("key"));
assert(!ssmap.contains("key"));
ssmap["a"] = "a";
ssmap["b"] = "b";
ssmap["c"] = "c";
ssmap["d"] = "d";
ssmap["e"] = "e";
ssmap.clear();
assert(!ssmap.contains("a"));
assert(!ssmap.contains("b"));
assert(!ssmap.contains("c"));
assert(!ssmap.contains("d"));
assert(!ssmap.contains("e"));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment