leetcodedsa-templates10-hashing28-hash-implementationC
#include <vector>
#include <string>
#include <utility>
#include <iostream>
 
using std::vector;
using std::string;
using std::pair;
using std::cout;
using std::endl;
 
class HashMap {
public:
    int size_ = 0;
    int capacity_ = 2;
    vector<pair<string, string>*> map_;
 
    HashMap() {
        map_ = *(new vector<pair<string, string>*> {0, 0});
    }
 
    int hash(string& key) {
        int index = 0;
        for (char &c: key) {
            index += int(c);
        }
        return index % capacity_;
    }
 
    string* get(string& key) {
        int index = hash(key);
        while (map_[index]) {
            if (map_[index]->first == key) {
                return &map_[index]->second;
            }
            index++;
            index = index % capacity_;
        }
        return nullptr;
    }
 
    void put(string& key, string& val) {
        int index = hash(key);
        while (true) {
            if (map_[index] == 0) {
                map_[index] = new pair<string, string>(key, val);
                size_++;
                if (size_ >= capacity_ / 2) {
                    rehash();
                }
                return;
            } else if (map_[index]->first == key) {
                map_[index]->second = val;
                return;
            }
            index++;
            index = index % capacity_;
        }
    }
 
    void remove(string& key) {
        if (!get(key)) {
            return;
        }
        int index = hash(key);
        while (true) {
            if (map_[index]->first == key) {
                // Removing an element using open-addressing actually causes a bug,
                // because we may create a hole in the list, and our get() may 
                // stop searching early when it reaches this hole.
                map_[index] = 0;
                size_--;
                return;
            }
            index++;
            index = index % capacity_;
        }
    }
 
    void rehash() {
        capacity_ = 2 * capacity_;
        vector<pair<string, string>*> newMap = *(new vector<pair<string, string>*>());
 
        for (int i = 0; i < capacity_; i++) {
            newMap.push_back(0);
        }
        vector<pair<string, string>*> oldMap = map_;
        map_ = newMap;
        size_ = 0;
        for (auto& pair: oldMap) {
            if (pair != 0) {
                put(pair->first, pair->second);
            }
        }
    }
 
    void print() {
        cout << "Printing size=" << size_ << endl; 
        for (auto& pair: map_) {
            if (pair) {
                cout << pair->first << ' ' << pair->second << '-';
            }
            cout << endl;
        }
    }
};```