Created
June 12, 2024 00:45
-
-
Save martin-minarik/5335150e34999c43f4097c07020e6bda to your computer and use it in GitHub Desktop.
Hash table
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "hash_table.h" | |
HashTable::HashTable() : table(16) {} | |
HashTable::HashTable(int size) : table(size) { | |
} | |
HashTable::~HashTable() = default; | |
bool HashTable::try_get_value(const string &key, int &value) const { | |
auto &bucket = table[hash_func(key)]; | |
if (!bucket.empty()) { | |
auto it = find_if(bucket.begin(), | |
bucket.end(), | |
[&](auto &item) { return item.first == key; }); | |
if (it != bucket.end()) { | |
value = (*it).second; | |
return true; | |
} | |
} | |
return false; | |
} | |
bool HashTable::contains_key(const string &key) const { | |
return !table[hash_func(key)].empty(); | |
} | |
void HashTable::insert(const string &key, int value) { | |
auto &bucket = table[hash_func(key)]; | |
auto it = find_if(bucket.begin(), | |
bucket.end(), | |
[&](auto &item) { return item.first == key; }); | |
if (it != bucket.end()) | |
(*it) = pair<string, int>(key, value); | |
else | |
bucket.emplace_back(key, value); | |
if (this->calc_load_factor() > 0.75) { | |
table.resize(table.size() * 2); | |
rehash(); | |
} | |
} | |
void HashTable::remove(const string &key) { | |
auto &bucket = table[hash_func(key)]; | |
if (!bucket.empty()) | |
bucket.erase(remove_if(bucket.begin(), | |
bucket.end(), | |
[&](auto &item) { return item.first == key; }), | |
bucket.end()); | |
} | |
void HashTable::clear() { | |
for (auto &bucket: table) | |
bucket.clear(); | |
} | |
size_t HashTable::get_table_size() const { | |
return table.size(); | |
} | |
int HashTable::hash_func(const string &key) const { | |
int sum = 0; | |
for (char chr: key) { | |
sum = (sum * PRIME_NUMBER) + chr; | |
} | |
return sum % get_table_size(); | |
} | |
size_t HashTable::get_number_of_keys() const { | |
int count = 0; | |
for (const auto &bucket: table) | |
count += (int) bucket.size(); | |
return count; | |
} | |
double HashTable::calc_load_factor() const { | |
return (double) get_number_of_keys() / (double) get_table_size(); | |
} | |
void HashTable::print() { | |
for (int i = 0; i < table.size(); ++i) { | |
cout << i << ". "; | |
for (const auto &item: table[i]) { | |
cout << "-->" << '(' << item.first << ": " << item.second << ')'; | |
} | |
cout << endl; | |
} | |
} | |
std::ostream &operator<<(std::ostream &os, const HashTable &hash_table) { | |
for (int i = 0; i < hash_table.table.size(); ++i) { | |
cout << i << ". "; | |
for (const auto &item: hash_table.table[i]) { | |
os << "-->" << '(' << item.first << ": " << item.second << ')'; | |
} | |
cout << endl; | |
} | |
return os; | |
} | |
void HashTable::rehash() { | |
vector<vector<pair<string, int>>> old_table = this->table; | |
table = vector<vector<pair<string, int>>>(table.size()); | |
for (const auto &bucket: old_table) | |
for (const auto &item: bucket) | |
table[hash_func(item.first)].push_back(item); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef HASH_TABLE_H | |
#define HASH_TABLE_H | |
#include <vector> | |
#include <ostream> | |
#include <iostream> | |
#include <utility> | |
#include <algorithm> | |
#include <stdexcept> | |
using namespace std; | |
class HashTable { | |
public: | |
HashTable(); | |
HashTable(int size); | |
virtual ~HashTable(); | |
bool contains_key(const string &key) const; | |
void insert(const string &key, int value); | |
void remove(const string &key); | |
void clear(); | |
bool try_get_value(const string &Key, int &Value) const; | |
size_t get_table_size() const; | |
size_t get_number_of_keys() const; | |
double calc_load_factor() const; | |
void print(); | |
friend std::ostream &operator<<(std::ostream &os, const HashTable &table); | |
private: | |
const static int PRIME_NUMBER = 137; | |
vector<vector<pair<string, int>>> table; | |
int hash_func(const string &key) const; | |
void rehash(); | |
}; | |
#endif //HASH_TABLE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include "hash_table.h" | |
using namespace std; | |
int main() { | |
cout << std::boolalpha; | |
HashTable hash_table(6); | |
{ | |
hash_table.insert("foo", 987); | |
hash_table.insert("abc", 123); | |
hash_table.insert("def", 456); | |
hash_table.insert("ghi", 789); | |
cout << hash_table; | |
} | |
cout << endl; | |
{ | |
hash_table.remove("ghi"); | |
cout << hash_table; | |
} | |
cout << endl; | |
{ | |
int value = 0; | |
cout << hash_table.try_get_value("def", value) << " " << value << endl; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment