From 46da1cceab37fa34e9cd46530e25ce0118cd37ee Mon Sep 17 00:00:00 2001 From: "github-classroom[bot]" <66690702+github-classroom[bot]@users.noreply.github.com> Date: Sat, 21 May 2022 11:10:53 +0000 Subject: [PATCH 1/2] Setting up GitHub Classroom Feedback From f0f5d93fac37a4eba33cece57dfe50e1c37c7578 Mon Sep 17 00:00:00 2001 From: Ruslan Date: Fri, 3 Jun 2022 19:27:06 +0300 Subject: [PATCH 2/2] first --- README.md | 4 +- src/chaining_hash_map.cpp | 211 ++++++++++++++++++++------------------ 2 files changed, 111 insertions(+), 104 deletions(-) diff --git a/README.md b/README.md index 2db39de..121aae1 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ ## 1. Информация о студенте -**Номер группы**: 00-000 +**Номер группы**: 11-109 -**Фамилия и Имя**: Иванов Иван +**Фамилия и Имя**: Ханин Руслан ## 2. Описание задания diff --git a/src/chaining_hash_map.cpp b/src/chaining_hash_map.cpp index c50d641..bc3868a 100644 --- a/src/chaining_hash_map.cpp +++ b/src/chaining_hash_map.cpp @@ -6,140 +6,147 @@ namespace assignment { - int hash(int key, int capacity) { - assert(capacity > 0); + int hash(int key, int capacity) { + assert(capacity > 0); - // Примечание: не забываем учесть отрицательные значения ключа. - return std::abs(key) % capacity; - } - - ChainingHashMap::ChainingHashMap(int capacity, double load_factor) : load_factor_{load_factor} { - - if (capacity <= 0) { - throw std::invalid_argument("capacity must be greater than zero"); - } - - if (load_factor <= 0.0 || load_factor > 1.0) { - throw std::invalid_argument("load factor must be in range (0...1]"); + // Примечание: не забываем учесть отрицательные значения ключа. + return std::abs(key) % capacity; } - // изначально, кол-во ключей равно нулю - num_keys_ = 0; + ChainingHashMap::ChainingHashMap(int capacity, double load_factor) : load_factor_{load_factor} { - // выделяем память под ячейки (корзинки) словаря - buckets_.resize(capacity); - } + if (capacity <= 0) { + throw std::invalid_argument("capacity must be greater than zero"); + } - bool ChainingHashMap::Put(int key, int value) { + if (load_factor <= 0.0 || load_factor > 1.0) { + throw std::invalid_argument("load factor must be in range (0...1]"); + } - // Tips: - // 1. Если ключ уже содержится в словаре, то возвращаем false. - // 2. Вычисляем индекс ячейки словаря при помощи хеш-функции. - // 3. Добавляем "ключ-значение" в найденную ячейку словаря. - // 4. Увеличиваем кол-во ключей в словаре. - // 5. Если превышен коэффициент загрузки словаря, то расширяем словарь. + // изначально, кол-во ключей равно нулю + num_keys_ = 0; - // ... (ниже представлена часть реализации) - - // вычисление индекса ячейки словаря по ключу - const int index = hash(key, buckets_.size()); - - // добавление пары "ключ-значение" в ячейку словаря (в конец связного списка) - buckets_[index].push_back(Node(key, value)); - - // расширение словаря до новой емкости в случае превышения коэффициента заполнения - if (num_keys_ / static_cast(buckets_.size()) > load_factor_) { - const int new_capacity = 0 /* здесь должна быть ваше выражение */; - resize(new_capacity); + // выделяем память под ячейки (корзинки) словаря + buckets_.resize(capacity); } - return true; - } + bool ChainingHashMap::Put(int key, int value) { + + // Tips: + // 1. Если ключ уже содержится в словаре, то возвращаем false. + // 2. Вычисляем индекс ячейки словаря при помощи хеш-функции. + // 3. Добавляем "ключ-значение" в найденную ячейку словаря. + // 4. Увеличиваем кол-во ключей в словаре. + // 5. Если превышен коэффициент загрузки словаря, то расширяем словарь. + + // ... (ниже представлена часть реализации) + + // вычисление индекса ячейки словаря по ключу + const int index = hash(key, buckets_.size()); + if (Contains(key)){ + return false; + } + // добавление пары "ключ-значение" в ячейку словаря (в конец связного списка) + buckets_[index].push_back(Node(key, value)); + num_keys_ += 1; + // расширение словаря до новой емкости в случае превышения коэффициента заполнения + if (num_keys_ / static_cast(buckets_.size()) > load_factor_) { + const int new_capacity = capacity() * kGrowthCoefficient /* здесь должна быть ваше выражение */; + resize(new_capacity); + } + return true; + } - std::optional ChainingHashMap::Remove(int key) { + std::optional ChainingHashMap::Remove(int key) { - const int index = 0 /* напишите здесь свой код */; + const int index = hash(key, capacity()); - // здесь используется итератор (по сути указатель на узел списка) - for (auto it = buckets_[index].begin(); it != buckets_[index].end(); ++it) { + // здесь используется итератор (по сути указатель на узел списка) + for (auto it = buckets_[index].begin(); it != buckets_[index].end(); ++it) { - if (it->key == key) { - // сохраняем данные удаляемого элемента - const int removed = it->value; + if (it->key == key) { + // сохраняем данные удаляемого элемента + const int removed = it->value; - // удаляем элемент из списка по итератору (указателю) - buckets_[index].erase(it); + // удаляем элемент из списка по итератору (указателю) + buckets_[index].erase(it); + num_keys_ -= 1; + // возвращаем значение удаленного элемента + return removed; + } + } - // возвращаем значение удаленного элемента - return removed; - } + return std::nullopt; } - return std::nullopt; - } + std::optional ChainingHashMap::Search(int key) const { - std::optional ChainingHashMap::Search(int key) const { + // вычисление индекса ячейки для указанного ключа + const int index = hash(key, capacity()); - // вычисление индекса ячейки для указанного ключа - const int index = 0 /* напишите здесь свой код */; - - // Проходимся по всем элемента в ячейке словаря. - // В худшем случае все элементы попали в одну ячейку словаря и сложность поиска ~ O(N). - for (const Node& node : buckets_[index]) { - // напишите здесь свой код ... + // Проходимся по всем элемента в ячейке словаря. + // В худшем случае все элементы попали в одну ячейку словаря и сложность поиска ~ O(N). + for (const Node& node : buckets_[index]) { + if(node.key == key){ + return node.value; + } + } + return std::nullopt; } - return std::nullopt; - } + void ChainingHashMap::Clear() { - void ChainingHashMap::Clear() { + // зачищаем каждую ячейку словаря + for (Bucket& bucket : buckets_) { + bucket.clear(); + } - // зачищаем каждую ячейку словаря - for (Bucket& bucket : buckets_) { - bucket.clear(); + // обнуляем кол-во ключей в словаре + num_keys_ = 0; } - // обнуляем кол-во ключей в словаре - num_keys_ = 0; - } + bool ChainingHashMap::Contains(int key) const { + const int index = hash(key, capacity()); + for (const Node& node: buckets_[index]){ + if(node.key == key){ + return true; + } + } + return false; + } - bool ChainingHashMap::Contains(int key) const { - // Напишите здесь свой код ... - return false; - } + bool ChainingHashMap::IsEmpty() const { + return num_keys_ == 0; + } - bool ChainingHashMap::IsEmpty() const { - return num_keys_ == 0; - } + int ChainingHashMap::capacity() const { + return buckets_.size(); + } - int ChainingHashMap::capacity() const { - return buckets_.size(); - } + int ChainingHashMap::size() const { + return num_keys_; + } - int ChainingHashMap::size() const { - return num_keys_; - } + double ChainingHashMap::load_factor() const { + return load_factor_; + } - double ChainingHashMap::load_factor() const { - return load_factor_; - } + void ChainingHashMap::resize(int new_capacity) { + assert(new_capacity > buckets_.size()); - void ChainingHashMap::resize(int new_capacity) { - assert(new_capacity > buckets_.size()); + // создаем новый словарь большего размера + auto new_buckets = std::vector(new_capacity); - // создаем новый словарь большего размера - auto new_buckets = std::vector(new_capacity); + // пересчитываем индексы элементов словаря, учитывая новую емкость + for (const Bucket& bucket : buckets_) { + for (const Node& node : bucket) { + const int new_index = hash(node.key, new_capacity); + new_buckets[new_index].push_back(node); + } + } - // пересчитываем индексы элементов словаря, учитывая новую емкость - for (const Bucket& bucket : buckets_) { - for (const Node& node : bucket) { - const int new_index = 0 /* напишите здесь свой код */; - new_buckets[new_index].push_back(node); - } + // обновляем поле (перемещаем данные из new_buckets в buckets_) + buckets_ = std::move(new_buckets); } - // обновляем поле (перемещаем данные из new_buckets в buckets_) - buckets_ = std::move(new_buckets); - } - -} // namespace assignment +} // namespace assignment \ No newline at end of file