diff --git a/README.md b/README.md index 190b1c3..4d35917 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## Имя студента -*Пожалуйста, добавьте вместо курсивного текста своё ФИО.* +Яковлев Алмаз Альбертович ## Описание задания diff --git a/src/hash_table.cpp b/src/hash_table.cpp index a581cb3..574a236 100644 --- a/src/hash_table.cpp +++ b/src/hash_table.cpp @@ -4,82 +4,106 @@ namespace itis { - int HashTable::hash(int key) const { - return utils::hash(key, static_cast(buckets_.size())); - } + int HashTable::hash(int key) const { + return utils::hash(key, static_cast(buckets_.size())); + } + + HashTable::HashTable(int capacity, double load_factor) : load_factor_{load_factor} { + if (capacity <= 0) { + throw std::logic_error("hash table capacity must be greater than zero"); // + } + + if (load_factor <= 0.0 || load_factor > 1.0) { + throw std:: logic_error("hash table load factor must be in range [0...1]"); + } + + buckets_.resize(capacity); + } + + std::optional HashTable::Search(int key) const { + int index = hash(key); + for (const auto& pair : buckets_[index]){ + if (pair.first == key) { + return pair.second; + } + } + return std::nullopt; + } - HashTable::HashTable(int capacity, double load_factor) : load_factor_{load_factor} { - if (capacity <= 0) { - throw std::logic_error("hash table capacity must be greater than zero"); + void HashTable::Put(int key, const std::string &value) { + int index = hash(key); + for (std::pair &pair: buckets_[index]){ + if (pair.first == key) { + pair.second = value; + return; + } + } + buckets_[index].push_back(std::pair(key, value)); + num_keys_++; + if (static_cast(num_keys_) / buckets_.size() >= load_factor_) { + std::vector new_buckets = std::vector{}; + new_buckets.resize(buckets_.size() * kGrowthCoefficient); + for (Bucket &bucket : buckets_){ + for (std::pair &pair : bucket){ + auto new_index = utils::hash(pair.first, new_buckets.size()); + new_buckets[new_index].push_back(pair); + } + } + buckets_ = new_buckets; + } } - if (load_factor <= 0.0 || load_factor > 1.0) { - throw std::logic_error("hash table load factor must be in range [0...1]"); + std::optional HashTable::Remove(int key) { + int index = hash(key); + for(const auto& pair:buckets_[index]){ + if(pair.first == key){ + auto value = pair; + buckets_[index].remove(pair); + return value.second; + } + } + return std::nullopt; } - // Tip: allocate hash-table buckets - } + bool HashTable::ContainsKey(int key) const { + // Note: uses Search(key) which is not initially implemented + return Search(key).has_value(); + } - std::optional HashTable::Search(int key) const { - // Tip: compute hash code (index) and use linear search - return std::nullopt; - } + bool HashTable::empty() const { + return size() == 0; + } - void HashTable::Put(int key, const std::string &value) { - // Tip 1: compute hash code (index) to determine which bucket to use - // Tip 2: consider the case when the key exists (read the docs in the header file) + int HashTable::size() const { + return num_keys_; + } - if (static_cast(num_keys_) / buckets_.size() >= load_factor_) { - // Tip 3: recompute hash codes (indices) for key-value pairs (create a new hash-table) - // Tip 4: use utils::hash(key, size) to compute new indices for key-value pairs + int HashTable::capacity() const { + return static_cast(buckets_.size()); } - } - - std::optional HashTable::Remove(int key) { - // Tip 1: compute hash code (index) to determine which bucket to use - // TIp 2: find the key-value pair to remove and make a copy of value to return - return std::nullopt; - } - - bool HashTable::ContainsKey(int key) const { - // Note: uses Search(key) which is not initially implemented - return Search(key).has_value(); - } - - bool HashTable::empty() const { - return size() == 0; - } - - int HashTable::size() const { - return num_keys_; - } - - int HashTable::capacity() const { - return static_cast(buckets_.size()); - } - - double HashTable::load_factor() const { - return load_factor_; - } - - std::unordered_set HashTable::keys() const { - std::unordered_set keys(num_keys_); - for (const auto &bucket : buckets_) { - for (const auto &[key, _] : bucket) { - keys.insert(key); - } + + double HashTable::load_factor() const { + return load_factor_; } - return keys; - } - - std::vector HashTable::values() const { - std::vector values; - for (const auto &bucket : buckets_) { - for (const auto &[_, value] : bucket) { - values.push_back(value); - } + + std::unordered_set HashTable::keys() const { + std::unordered_set keys(num_keys_); + for (const auto &bucket : buckets_) { + for (const auto &[key, _] : bucket) { + keys.insert(key); + } + } + return keys; + } + + std::vector HashTable::values() const { + std::vector values; + for (const auto &bucket : buckets_) { + for (const auto &[_, value] : bucket) { + values.push_back(value); + } + } + return values; } - return values; - } } // namespace itis \ No newline at end of file