시리즈: Algorithms
cpp
134 줄
· 업데이트 2026-04-18
hash_table_chaining.cpp
Algorithms/Hash/cpp/hash_table_chaining.cpp
/**
* Hash table with separate chaining, dynamic rehashing.
* Teaching demo: string keys, int values, division method h(k)=hash_code(k)%m.
*/
#include <iostream>
#include <list>
#include <string>
#include <utility>
#include <vector>
class HashMapChaining {
static constexpr double kMaxLoadFactor = 0.75;
struct Entry {
std::string key;
int value;
};
std::vector<std::list<Entry>> buckets_;
std::size_t size_{0};
static std::size_t strHash(const std::string& s) {
std::size_t h = 5381;
for (unsigned char c : s) {
h = ((h << 5) + h) + c; // DJB2-style
}
return h;
}
std::size_t indexFor(const std::string& key) const {
return strHash(key) % buckets_.size();
}
void rehash(std::size_t new_m) {
std::vector<std::list<Entry>> old = std::move(buckets_);
buckets_.assign(new_m, {});
size_ = 0;
for (auto& chain : old) {
for (auto& e : chain) {
insertUnchecked(std::move(e.key), e.value);
}
}
}
void insertUnchecked(std::string key, int value) {
std::size_t idx = strHash(key) % buckets_.size();
for (auto& e : buckets_[idx]) {
if (e.key == key) {
e.value = value;
return;
}
}
buckets_[idx].push_back(Entry{std::move(key), value});
++size_;
}
void ensureCapacity() {
if (buckets_.empty()) {
buckets_.assign(7, {});
return;
}
double alpha = static_cast<double>(size_) / static_cast<double>(buckets_.size());
if (alpha <= kMaxLoadFactor) return;
// next prime-ish size
std::size_t nm = buckets_.size() * 2 + 1;
rehash(nm);
}
public:
void insert(const std::string& key, int value) {
ensureCapacity();
std::size_t idx = indexFor(key);
for (auto& e : buckets_[idx]) {
if (e.key == key) {
e.value = value;
return;
}
}
buckets_[idx].push_back(Entry{key, value});
++size_;
}
bool find(const std::string& key, int& out) const {
if (buckets_.empty()) return false;
std::size_t idx = indexFor(key);
for (const auto& e : buckets_[idx]) {
if (e.key == key) {
out = e.value;
return true;
}
}
return false;
}
bool erase(const std::string& key) {
if (buckets_.empty()) return false;
std::size_t idx = indexFor(key);
auto& chain = buckets_[idx];
for (auto it = chain.begin(); it != chain.end(); ++it) {
if (it->key == key) {
chain.erase(it);
--size_;
return true;
}
}
return false;
}
std::size_t bucketCount() const { return buckets_.size(); }
std::size_t size() const { return size_; }
double loadFactor() const {
if (buckets_.empty()) return 0;
return static_cast<double>(size_) / static_cast<double>(buckets_.size());
}
};
int main() {
HashMapChaining map;
map.insert("apple", 1);
map.insert("banana", 2);
map.insert("grape", 3);
int v = 0;
if (map.find("banana", v)) std::cout << "banana -> " << v << "\n";
std::cout << "size=" << map.size() << " buckets=" << map.bucketCount()
<< " load_factor=" << map.loadFactor() << "\n";
for (int i = 0; i < 50; ++i) {
map.insert("k" + std::to_string(i), i);
}
std::cout << "after bulk insert: size=" << map.size()
<< " buckets=" << map.bucketCount()
<< " load_factor=" << map.loadFactor() << "\n";
return 0;
}
관련 글
Algorithms
java
업데이트 2026-03-02
#include <iostream>.java
#include <iostream>.java — java source code from the Algorithms learning materials (Algorithms/#include <iostream>.java).
글 읽기 →
Algorithms
cpp
업데이트 2026-04-07
748.cpp
748.cpp — cpp source code from the Algorithms learning materials (Algorithms/748.cpp).
글 읽기 →
Algorithms
cpp
업데이트 2026-04-07
827.cpp
827.cpp — cpp source code from the Algorithms learning materials (Algorithms/827.cpp).
글 읽기 →
Algorithms
cpp
업데이트 2026-04-07
827_best_greedy.cpp
827_best_greedy.cpp — cpp source code from the Algorithms learning materials (Algorithms/827_best_greedy.cpp).
글 읽기 →
Algorithms
cpp
업데이트 2026-04-07
8402.cpp
8402.cpp — cpp source code from the Algorithms learning materials (Algorithms/8402.cpp).
글 읽기 →
Algorithms
cpp
업데이트 2026-04-07
860.cpp
860.cpp — cpp source code from the Algorithms learning materials (Algorithms/860.cpp).
글 읽기 →