diff --git a/lib/src/util.hpp b/lib/src/util.hpp index e69de29b..675809a0 100644 --- a/lib/src/util.hpp +++ b/lib/src/util.hpp @@ -0,0 +1,27 @@ +#pragma once +#include +#include +#include +#include + +template +int Partition(std::vector& arr, int l, int r) { + std::srand(std::time(nullptr)); + int pv_index = l + std::rand() % (r - l + 1); + T pivot = arr[pv_index]; + std::swap(arr[pv_index], arr[(l + r) / 2]); + int i = l, j = r; + while (i <= j) { + while (arr[i] < pivot) { + i++; + } + while (arr[j] > pivot) { + j--; + } + if (i >= j) { + break; + } + std::swap(arr[i++], arr[j--]); + } + return j; +} \ No newline at end of file diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index ef5a86ae..babf52ce 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -1,7 +1,7 @@ #include -#include "topology_sort.hpp" +#include "utils.hpp" TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); // Stack [] diff --git a/task_01/src/topology_sort.cpp b/task_01/src/topology_sort.cpp deleted file mode 100644 index e53f670c..00000000 --- a/task_01/src/topology_sort.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "topology_sort.hpp" diff --git a/task_01/src/utils.cpp b/task_01/src/utils.cpp new file mode 100644 index 00000000..0ee624c5 --- /dev/null +++ b/task_01/src/utils.cpp @@ -0,0 +1 @@ +#include "utils.hpp" diff --git a/task_01/src/topology_sort.hpp b/task_01/src/utils.hpp similarity index 100% rename from task_01/src/topology_sort.hpp rename to task_01/src/utils.hpp diff --git a/task_02/src/main.cpp b/task_02/src/main.cpp index 0e4393ba..87ff7786 100644 --- a/task_02/src/main.cpp +++ b/task_02/src/main.cpp @@ -1,3 +1,4 @@ #include +#include "stack.hpp" int main() { return 0; } diff --git a/task_02/src/stack.cpp b/task_02/src/stack.cpp index 8ca89902..06af66bf 100644 --- a/task_02/src/stack.cpp +++ b/task_02/src/stack.cpp @@ -2,20 +2,48 @@ #include -void Stack::Push(int value) { data_.push(value); } +void Stack::Push(int value) { + Node* t = new Node(); + t->value_ = value; + if (top_ == nullptr) { + top_ = t; + } else { + t->prev_ = top_; + top_ = t; + } +} + +bool Stack::CheckTop() { + if (Top() == nullptr) { + return true; + } else { + return false; + } +} + +int Stack::GetTopValue() { return Top()->value_; } int Stack::Pop() { - auto result = data_.top(); - data_.pop(); - return result; + Node* t = top_; + top_ = top_->prev_; + int value = t->value_; + delete t; + return value; } -void MinStack::Push(int value) { data_.push_back(value); } +Stack::Node* Stack::Top() { return top_; } +void MinStack::Push(int value) { + if (data_.CheckTop()) { + min_values_.Push(value); + } else { + min_values_.Push(std::min(value, data_.GetTopValue())); + } + data_.Push(value); +} int MinStack::Pop() { - auto result = data_.back(); - data_.pop_back(); - return result; + int t = min_values_.Pop(); + return data_.Pop(); } -int MinStack::GetMin() { return *std::min_element(data_.begin(), data_.end()); } \ No newline at end of file +int MinStack::GetMin() { return min_values_.GetTopValue(); } \ No newline at end of file diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp index 138ec40f..4445fcd1 100644 --- a/task_02/src/stack.hpp +++ b/task_02/src/stack.hpp @@ -1,15 +1,19 @@ #pragma once -#include -#include - class Stack { + private: + struct Node { + int value_ = 0; + Node* prev_ = nullptr; + }; + Node* top_ = nullptr; + Node* Top(); + public: void Push(int value); int Pop(); - - private: - std::stack data_; + bool CheckTop(); + int GetTopValue(); }; class MinStack { @@ -19,5 +23,6 @@ class MinStack { int GetMin(); private: - std::vector data_; + Stack data_; + Stack min_values_; }; diff --git a/task_03/src/temp_up_days.cpp b/task_03/src/temp_up_days.cpp new file mode 100644 index 00000000..57a2c760 --- /dev/null +++ b/task_03/src/temp_up_days.cpp @@ -0,0 +1,23 @@ +#include "temp_up_days.hpp" + +#include + +std::vector TempUpDayCounter(std::vector temps) { + std::stack days; + std::vector result(temps.size(), 0); + for (int i = 0; i < temps.size(); i++) { + Day d; + d.index_ = i; + d.temp_ = temps[i]; + while (!days.empty()) { + if (days.top().temp_ < d.temp_) { + result[days.top().index_] = d.index_ - days.top().index_; + days.pop(); + } else { + break; + } + } + days.push(d); + } + return result; +} \ No newline at end of file diff --git a/task_03/src/temp_up_days.hpp b/task_03/src/temp_up_days.hpp new file mode 100644 index 00000000..ab255eb3 --- /dev/null +++ b/task_03/src/temp_up_days.hpp @@ -0,0 +1,9 @@ +#pragma once +#include + +struct Day { + int index_; + int temp_; +}; + +std::vector TempUpDayCounter(std::vector temps); diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index ef5a86ae..539ca88c 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,8 +1,21 @@ #include -#include "topology_sort.hpp" +#include "temp_up_days.hpp" -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +TEST(TempUpDays, Simple) { + ASSERT_EQ(TempUpDayCounter(std::vector{5, 7, 4, 5}), + (std::vector{1, 0, 1, 0})); + ASSERT_EQ(TempUpDayCounter(std::vector{5, 12, 4, 9, 5, 4, 2}), + (std::vector{1, 0, 1, 0, 0, 0, 0})); + ASSERT_EQ(TempUpDayCounter(std::vector{2, 6, 17, 7, 3, 4}), + (std::vector{1, 1, 0, 0, 1, 0})); + ASSERT_EQ(TempUpDayCounter(std::vector{}), std::vector{}); + + ASSERT_EQ(TempUpDayCounter( + std::vector{70, 41, 86, 49, 31, 71, 39, 79, 24, 46}), + (std::vector{2, 1, 0, 2, 1, 2, 1, 0, 1, 0})); + ASSERT_EQ(TempUpDayCounter(std::vector{84, 44, 32, 65, 33, 11, 70, 57, + 73, 98, 52, 93}), + (std::vector{9, 2, 1, 3, 2, 1, 2, 1, 1, 0, 1, 0})); } diff --git a/task_03/src/topology_sort.cpp b/task_03/src/topology_sort.cpp deleted file mode 100644 index e53f670c..00000000 --- a/task_03/src/topology_sort.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "topology_sort.hpp" diff --git a/task_03/src/topology_sort.hpp b/task_03/src/topology_sort.hpp deleted file mode 100644 index 6f70f09b..00000000 --- a/task_03/src/topology_sort.hpp +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/task_04/src/heap.cpp b/task_04/src/heap.cpp new file mode 100644 index 00000000..fa06672e --- /dev/null +++ b/task_04/src/heap.cpp @@ -0,0 +1,61 @@ +#include "heap.hpp" + +#include +#include +#include + +void Heap::SiftUp(int index) { + while (index >= 0 && heap_[index] < heap_[(index - 1) / 2]) { + std::swap(heap_[index], heap_[(index - 1) / 2]); + index = (index - 1) / 2; + } +} + +void Heap::SiftDown(int index) { + while (2 * index + 1 < heap_.size()) { + int left = 2 * index + 1; + int right = 2 * index + 2; + int small_child_index = left; + if (right < heap_.size() && heap_[right] < heap_[left]) { + small_child_index = right; + } + if (heap_[index] < heap_[small_child_index]) { + break; + } + std::swap(heap_[index], heap_[small_child_index]); + index = small_child_index; + } +} + +int Heap::Min() { + if (Size() == 0) throw std::runtime_error("Empty Heap"); + int m = heap_[0]; + std::swap(heap_[0], heap_[heap_.size() - 1]); + heap_.pop_back(); + SiftDown(0); + return m; +} + +void Heap::Insert(int value) { + heap_.push_back(value); + this->SiftUp(heap_.size() - 1); +} + +void Heap::Build(std::vector data) { + for (auto x : data) { + this->Insert(x); + } +} + +int Heap::Size() { return heap_.size(); } + +int Heap::Top() { + if (Size() == 0) throw std::runtime_error("Empty Heap"); + return heap_[0]; +} + +int FindMin(std::vector data) { + Heap heap; + heap.Build(data); + return heap.Min(); +} diff --git a/task_04/src/heap.hpp b/task_04/src/heap.hpp new file mode 100644 index 00000000..29255f59 --- /dev/null +++ b/task_04/src/heap.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +class Heap { + public: + int Top(); + int Size(); + int Min(); + void Insert(int value); + void Build(std::vector data); + + private: + std::vector heap_; + void SiftUp(int index); + void SiftDown(int index); +}; + +int FindMin(std::vector data); \ No newline at end of file diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp index 5e11617e..49da1095 100644 --- a/task_04/src/test.cpp +++ b/task_04/src/test.cpp @@ -1,6 +1,33 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "heap.hpp" + +TEST(HeapMin, Simple) { + ASSERT_EQ(FindMin(std::vector{4, 5, 16, 3, 6}), 3); + ASSERT_EQ(FindMin(std::vector{29, 25, 10, 13, 14, 23, 4, 6}), 4); + ASSERT_EQ(FindMin(std::vector{29, 17, 16, 27, 6, 11}), 6); +} + +TEST(EmptyHeap, Simple) { + Heap empty_heap; + + ASSERT_EQ(empty_heap.Size(), 0); + EXPECT_THROW(empty_heap.Top(), std::runtime_error); + EXPECT_THROW(empty_heap.Min(), std::runtime_error); } + +TEST(Heap, Simple) { + Heap heap; + heap.Insert(5); + heap.Insert(3); + + ASSERT_EQ(heap.Size(), 2); + ASSERT_EQ(heap.Top(), 3); + + ASSERT_EQ(heap.Min(), 3); + + ASSERT_EQ(heap.Size(), 1); + ASSERT_EQ(heap.Top(), 5); +} \ No newline at end of file diff --git a/task_05/src/main.cpp b/task_05/src/main.cpp index 0e4393ba..c2134b68 100644 --- a/task_05/src/main.cpp +++ b/task_05/src/main.cpp @@ -1,3 +1,6 @@ #include +#include + +#include "qsort.hpp" int main() { return 0; } diff --git a/task_05/src/qsort.cpp b/task_05/src/qsort.cpp new file mode 100644 index 00000000..e69de29b diff --git a/task_05/src/qsort.hpp b/task_05/src/qsort.hpp new file mode 100644 index 00000000..63752ae9 --- /dev/null +++ b/task_05/src/qsort.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include +#include +#include + +template +void QuickSort(std::vector& arr, int l, int r) { + if (l < r) { + int q = Partition(arr, l, r); + QuickSort(arr, l, q); + QuickSort(arr, q + 1, r); + } +} diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index 5e11617e..4c48f0d8 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -1,6 +1,36 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "qsort.hpp" + +TEST(Qsort, Simple1) { + std::vector vec = {77, 42, 19, 53, 18, 20}; + QuickSort(vec, 0, vec.size() - 1); + ASSERT_EQ((vec), (std::vector{18, 19, 20, 42, 53, 77})); +} + +TEST(Qsort, Simple2) { + std::vector vec2{12.75, 5.3, 1.1, 23.223, -13.1, 37.37}; + QuickSort(vec2, 0, vec2.size() - 1); + ASSERT_EQ((vec2), + (std::vector{-13.1, 1.1, 5.3, 12.75, 23.223, 37.37})); +} + +TEST(Qsort, Simple3) { + std::vector vec3 = {-1, 2, -1, 3, 4, 5, 2}; + QuickSort(vec3, 0, vec3.size() - 1); + ASSERT_EQ((vec3), (std::vector{-1, -1, 2, 2, 3, 4, 5})); +} + +TEST(Qsort, Simple4) { + std::vector vec4{2, 4, 2, 1, 3, 4, 1}; + QuickSort(vec4, 0, vec4.size() - 1); + ASSERT_EQ((vec4), (std::vector{1, 1, 2, 2, 3, 4, 4})); +} + +TEST(Qsort, Simple5) { + std::vector vec5{}; + QuickSort(vec5, 0, vec5.size() - 1); + ASSERT_EQ((vec5), std::vector{}); } diff --git a/task_06/src/order_stats.hpp b/task_06/src/order_stats.hpp new file mode 100644 index 00000000..9df85de1 --- /dev/null +++ b/task_06/src/order_stats.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include +#include + +template +int Partition(std::vector& data, int l, int r) { + std::srand(std::time(nullptr)); + int pivot_pos = l + std::rand() % (r - l); + if (pivot_pos != r - 1) { + std::swap(data[r - 1], data[pivot_pos]); + } + + int i = l, j = l; + T pivot = data[r - 1]; + while (j < r - 1) { + if (data[j] <= pivot) { + std::swap(data[i++], data[j]); + } + j++; + } + if (i != r - 1) { + std::swap(data[i], data[r - 1]); + } + return i; +} + +template +T FindKStatistics(std::vector& data, int l, int r, int k) { + int lastPivotPos = 0, left = l, right = r; + while (left < right) { + if ((lastPivotPos = Partition(data, left, right)) == k) { + return data[lastPivotPos]; + } else if (lastPivotPos > k) { + right = lastPivotPos; + } else { + left = lastPivotPos + 1; + } + } + return data[lastPivotPos]; +} diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 5e11617e..dffc0874 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,6 +1,29 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "order_stats.hpp" + +TEST(OrderStats, Simple1) { + std::vector v{50, 82, 11, 64, 66, 57, 35}; + ASSERT_EQ(FindKStatistics(v, 0, v.size(), 3), 57); +} +TEST(OrderStats, Simple2) { + std::vector v{ + 40, 99, 63, 22, 37, 60, 61, 8, 84, 97, + }; + ASSERT_EQ(FindKStatistics(v, 0, v.size(), 5), 61); +} +TEST(OrderStats, Simple3) { + std::vector v{69, 91, 69, 64, 18, 76, 28, 9, 59, 40, 22, 48}; + ASSERT_EQ(FindKStatistics(v, 0, v.size(), 0), 9); +} +TEST(OrderStats, Simple4) { + std::vector v{84.68, 39.62, 36.57, 17.44, 34.22, 66.11, 57.68, 1.58}; + ASSERT_EQ(FindKStatistics(v, 0, v.size(), 2), 34.22); +} + +TEST(OrderStats, Simple5) { + std::vector v{'d', 's', 'a', 'b'}; + ASSERT_EQ(FindKStatistics(v, 0, v.size(), 1), 'b'); } diff --git a/task_07/src/test.cpp b/task_07/src/test.cpp index 5e11617e..dbda586a 100644 --- a/task_07/src/test.cpp +++ b/task_07/src/test.cpp @@ -1,6 +1,56 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "tree.hpp" + +TEST(AVLTree, EmptyTree) { + Tree avl; + ASSERT_EQ(avl.Contains(10), false); + ASSERT_EQ(avl.Contains(5), false); + ASSERT_EQ(avl.Contains(0), false); +} + +TEST(AVLTree, AddElements) { + Tree avl; + avl.Push(10); + avl.Push(5); + avl.Push(15); + ASSERT_EQ(avl.Contains(10), true); + ASSERT_EQ(avl.Contains(5), true); + ASSERT_EQ(avl.Contains(15), true); +} + +TEST(AVLTree, RemoveElements) { + Tree avl; + avl.Push(10); + avl.Push(5); + avl.Push(15); + avl.Pop(5); + ASSERT_EQ(avl.Contains(5), false); +} + +TEST(AVLTree, ContainsMethod) { + Tree avl; + avl.Push(10); + avl.Push(5); + ASSERT_EQ(avl.Contains(10), true); + ASSERT_EQ(avl.Contains(5), true); + ASSERT_EQ(avl.Contains(15), false); } + +TEST(AVLTree, RemoveNonExistentElement) { + Tree avl; + avl.Push(10); + avl.Push(5); + avl.Pop(15); + ASSERT_EQ(avl.Contains(15), false); +} + +TEST(AVLTree, RemoveInEmptyTree) { + Tree avl; + ASSERT_EQ(avl.Contains(13), false); + avl.Pop(13); + ASSERT_EQ(avl.Contains(13), false); + ASSERT_EQ(avl.Contains(37), false); +} \ No newline at end of file diff --git a/task_07/src/tree.hpp b/task_07/src/tree.hpp new file mode 100644 index 00000000..f4a89e6e --- /dev/null +++ b/task_07/src/tree.hpp @@ -0,0 +1,162 @@ +#pragma once + +#include +#include + +template +struct Node { + T key; + unsigned int height = 1; + Node* left = nullptr; + Node* right = nullptr; + Node(T k) : key{k} {}; +}; + +template +class Tree { // AVl-tree + public: + void Push(int k); + void Pop(int k); + bool Contains(int k); + + private: + unsigned int Height(Node* node_ptr); + int BFactor(Node* node_ptr); + void FixHeight(Node* node_ptr); + Node* RotateRight(Node* node_ptr); + Node* RotateLeft(Node* node_ptr); + Node* Balance(Node* node_ptr); + Node* Insert(Node* node_ptr, T k); + Node* FindMin(Node* node_ptr); + Node* RemoveMin(Node* node_ptr); + Node* Remove(Node* node_ptr, int k); + Node* Find(Node* node_ptr, int k); + Node* root_ = nullptr; +}; + +template +void Tree::Push(int k) { + root_ = Insert(root_, k); +} +template +void Tree::Pop(int k) { + root_ = Remove(root_, k); +} +template +bool Tree::Contains(int k) { + return Find(root_, k) ? true : false; +} + +template +unsigned int Tree::Height(Node* node_ptr) { + return node_ptr ? node_ptr->height : 0; +} + +template +int Tree::BFactor(Node* node_ptr) { + return Height(node_ptr->right) - Height(node_ptr->left); +} + +template +void Tree::FixHeight(Node* node_ptr) { + unsigned int hl = Height(node_ptr->left); + unsigned int hr = Height(node_ptr->right); + node_ptr->height = std::max(hl, hr) + 1; +} + +template +Node* Tree::RotateRight(Node* node_ptr) { + Node* q = node_ptr->left; + node_ptr->left = q->right; + q->right = node_ptr; + FixHeight(node_ptr); + FixHeight(q); + return q; +} + +template +Node* Tree::RotateLeft(Node* node_ptr) { + Node* q = node_ptr->right; + node_ptr->right = q->left; + q->left = node_ptr; + FixHeight(q); + FixHeight(node_ptr); + return q; +} + +template +Node* Tree::Balance(Node* node_ptr) { + FixHeight(node_ptr); + if (BFactor(node_ptr) == 2) { + if (BFactor(node_ptr->right) < 0) + node_ptr->right = RotateRight(node_ptr->right); + return RotateLeft(node_ptr); + } + if (BFactor(node_ptr) == -2) { + if (BFactor(node_ptr->left) > 0) + node_ptr->left = RotateLeft(node_ptr->left); + return RotateRight(node_ptr); + } + return node_ptr; +} + +template +Node* Tree::Insert(Node* node_ptr, T k) { + if (!node_ptr) return new Node(k); + if (k < node_ptr->key) + node_ptr->left = Insert(node_ptr->left, k); + else + node_ptr->right = Insert(node_ptr->right, k); + return Balance(node_ptr); +} + +template +Node* Tree::FindMin(Node* node_ptr) { + return node_ptr->left ? FindMin(node_ptr->left) : node_ptr; +} + +template +Node* Tree::RemoveMin(Node* node_ptr) { + if (node_ptr->left == nullptr) { + return node_ptr->right; + } + node_ptr->left = RemoveMin(node_ptr->left); + return Balance(node_ptr); +} + +template +Node* Tree::Remove(Node* node_ptr, int k) { + if (!node_ptr) { + return nullptr; + } + if (k < node_ptr->key) { + node_ptr->left = Remove(node_ptr->left, k); + } else if (k > node_ptr->key) { + node_ptr->right = Remove(node_ptr->right, k); + } else { + Node* l = node_ptr->left; + Node* r = node_ptr->right; + delete node_ptr; + if (!r) { + return l; + } + Node* m = FindMin(r); + m->right = RemoveMin(r); + m->left = l; + return Balance(m); + } + return Balance(node_ptr); +} + +template +Node* Tree::Find(Node* node_ptr, int k) { + if (node_ptr == nullptr || node_ptr->key == k) { + return node_ptr; + } + if (k < node_ptr->key) { + return Find(node_ptr->left, k); + } + if (k > node_ptr->key) { + return Find(node_ptr->right, k); + } +} \ No newline at end of file diff --git a/task_08/src/hashtable.cpp b/task_08/src/hashtable.cpp new file mode 100644 index 00000000..64c60604 --- /dev/null +++ b/task_08/src/hashtable.cpp @@ -0,0 +1,89 @@ +#include "hashtable.hpp" + +#include + +unsigned HashTable::HashFunction1(int key) { + return floor(buffer_size_ * ((key * HashCoeff) - floor(key * HashCoeff))); +} + +unsigned HashTable::HashFunction2(int key) { + return (key * buffer_size_ - 1) % buffer_size_; +} + +void HashTable::Resize() { + buffer_size_ *= 2; + table_.resize(buffer_size_); + cell_status_.resize(buffer_size_); +} + +void HashTable::Clear() { + size_ = 0; + used_cell_size_ = 0; + for (int i = 0; i < buffer_size_; i++) { + cell_status_[i] = Status::Empty; + } +} +void HashTable::Rehash() { + std::vector temp; + for (int i = 0; i < buffer_size_; i++) { + if (cell_status_[i] == Status::Fill) { + temp.push_back(table_[i]); + } + } + Resize(); + Clear(); + for (int i = 0; i < temp.size(); i++) { + Insert(temp[i]); + } +} + +void HashTable::Insert(int key) { + unsigned hash = HashFunction1(key) % buffer_size_; + int counter = 0; + while (cell_status_[hash] == Status::Fill) { + if (table_[hash] == key) { + return; + } + counter++; + hash = (HashFunction1(key) + counter * HashFunction2(key)) % buffer_size_; + } + table_[hash] = key; + cell_status_[hash] = Status::Fill; + used_cell_size_++; + size_++; + + double fill_coeff = double(used_cell_size_) / buffer_size_; + if (fill_coeff >= RehashSize) Rehash(); +} + +void HashTable::Remove(int key) { + unsigned hash = HashFunction1(key) % buffer_size_; + int counter = 0; + while (cell_status_[hash] != Status::Empty) { + if (table_[hash] == key && cell_status_[hash] == Status::Deleted) { + return; + } + if (table_[hash] == key && cell_status_[hash] == Status::Fill) { + size_--; + cell_status_[hash] = Status::Deleted; + return; + } + counter++; + hash = (HashFunction1(key) + counter * HashFunction2(key)) % buffer_size_; + } +} + +bool HashTable::Contains(int key) { + unsigned hash = HashFunction1(key) % buffer_size_; + int counter = 0; + while (cell_status_[hash] != Status::Empty) { + if (table_[hash] == key && cell_status_[hash] == Status::Fill) { + return true; + } + counter++; + hash = (HashFunction1(key) + counter * HashFunction2(key)) % buffer_size_; + } + return false; +} + +unsigned HashTable::Size() { return size_; } \ No newline at end of file diff --git a/task_08/src/hashtable.hpp b/task_08/src/hashtable.hpp new file mode 100644 index 00000000..4d4027b3 --- /dev/null +++ b/task_08/src/hashtable.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include + +class HashTable { + public: + HashTable() + : size_{0}, + buffer_size_{DefaultSize}, + used_cell_size_{0}, + table_{std::vector(buffer_size_)}, + cell_status_{std::vector(buffer_size_, Status::Empty)} {}; + void Insert(int key); + void Remove(int key); + bool Contains(int key); + unsigned Size(); + + private: + constexpr static const int DefaultSize = 8; + constexpr static const double RehashSize = 0.75; + constexpr static const double HashCoeff = 0.61803398; + unsigned size_; // занятые ячейки без учёта Deleted + unsigned buffer_size_; + unsigned used_cell_size_; // занятые ячейки с учётом Deleted + std::vector table_; + enum class Status { Empty, Deleted, Fill }; + std::vector cell_status_; + + unsigned HashFunction1(int key); + unsigned HashFunction2(int key); + void Rehash(); + void Resize(); + void Clear(); +}; diff --git a/task_08/src/test.cpp b/task_08/src/test.cpp index 5e11617e..3e12290c 100644 --- a/task_08/src/test.cpp +++ b/task_08/src/test.cpp @@ -1,6 +1,34 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "hashtable.hpp" + +TEST(Hashtable, Simple) { + HashTable table; + table.Insert(5); + table.Insert(17); + table.Insert(33); + ASSERT_EQ(table.Contains(17), true); + ASSERT_EQ(table.Size(), 3); + table.Remove(5); + ASSERT_EQ(table.Contains(5), false); +} + +TEST(Hashtable, EmptyTable) { + HashTable table; + ASSERT_EQ(table.Size(), 0); + ASSERT_EQ(table.Contains(10), false); } + +TEST(Hashtable, RemoveNonExistentElement) { + HashTable table; + table.Insert(7); + table.Remove(10); + ASSERT_EQ(table.Size(), 1); +} + +TEST(Hashtable, InsertDuplicateElement) { + HashTable table; + table.Insert(5); + table.Insert(5); + ASSERT_EQ(table.Size(), 1); +} \ No newline at end of file diff --git a/task_09/src/change_money.cpp b/task_09/src/change_money.cpp new file mode 100644 index 00000000..399b30da --- /dev/null +++ b/task_09/src/change_money.cpp @@ -0,0 +1,16 @@ +#include "change_money.hpp" + +#include + +int CoinExchange(int sum, std::vector coins) { + std::vector money(sum + 1, 1e9); + money[0] = 0; + for (int m = 1; m <= sum; m++) { + for (auto coin : coins) { + if (coin <= m) { + money[m] = std::min(money[m], money[m - coin] + 1); + } + } + } + return money[sum]; +} \ No newline at end of file diff --git a/task_09/src/change_money.hpp b/task_09/src/change_money.hpp new file mode 100644 index 00000000..ec7b644d --- /dev/null +++ b/task_09/src/change_money.hpp @@ -0,0 +1,4 @@ +#pragma once + +#include +int CoinExchange(int sum, std::vector coins); \ No newline at end of file diff --git a/task_09/src/test.cpp b/task_09/src/test.cpp index 869094dd..b702efd2 100644 --- a/task_09/src/test.cpp +++ b/task_09/src/test.cpp @@ -1,4 +1,14 @@ - #include -TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); } +#include + +#include "change_money.hpp" + +TEST(ChangeMoney, Simple) { + ASSERT_EQ(CoinExchange(14, std::vector{1, 2, 5, 10}), 3); + ASSERT_EQ(CoinExchange(21, std::vector{1, 3, 6}), 4); + ASSERT_EQ(CoinExchange(25, std::vector{1, 2, 3, 5}), 5); + ASSERT_EQ(CoinExchange(137, std::vector{1, 3, 7, 19}), 9); + + ASSERT_EQ(CoinExchange(14, std::vector{1, 2, 5, 7, 10}), 2); +}