diff --git a/task_02/src/min_stack.cpp b/task_02/src/min_stack.cpp new file mode 100644 index 00000000..e69de29b diff --git a/task_02/src/min_stack.hpp b/task_02/src/min_stack.hpp new file mode 100644 index 00000000..7a885a11 --- /dev/null +++ b/task_02/src/min_stack.hpp @@ -0,0 +1,45 @@ +#ifndef MIN_STACK_HPP +#define MIN_STACK_HPP +#include +#include +#include + +#include "stack.hpp" + +template +class MinStack { + public: + void push(T value) { + if ((getMin_()) && *getMin_() < value) + min_.push(getMin()); + else + min_.push(value); + data_.push(value); + } + T pop() { + T result = data_.pop(); + min_.pop(); + return result; + } + T getMin() { + T result = min_.pop(); + min_.push(result); + return result; + } + + private: + std::optional getMin_() { + std::optional result; + try { + result = min_.pop(); + min_.push(*result); + } catch (std::exception& e) { + result = std::nullopt; + } + return result; + } + Stack data_; + Stack min_; +}; + +#endif \ No newline at end of file diff --git a/task_02/src/stack.cpp b/task_02/src/stack.cpp index 8ca89902..e69de29b 100644 --- a/task_02/src/stack.cpp +++ b/task_02/src/stack.cpp @@ -1,21 +0,0 @@ -#include "stack.hpp" - -#include - -void Stack::Push(int value) { data_.push(value); } - -int Stack::Pop() { - auto result = data_.top(); - data_.pop(); - return result; -} - -void MinStack::Push(int value) { data_.push_back(value); } - -int MinStack::Pop() { - auto result = data_.back(); - data_.pop_back(); - return result; -} - -int MinStack::GetMin() { return *std::min_element(data_.begin(), data_.end()); } \ No newline at end of file diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp index 138ec40f..225307b2 100644 --- a/task_02/src/stack.hpp +++ b/task_02/src/stack.hpp @@ -1,23 +1,22 @@ -#pragma once - -#include +#ifndef STACK_HPP +#define STACK_HPP +#include +#include #include +template class Stack { public: - void Push(int value); - int Pop(); + void push(T value) { data_.push_back(value); } + T pop() { + if (data_.empty()) throw std::runtime_error("stack is empty"); + int result = data_.back(); + data_.pop_back(); + return result; + } private: - std::stack data_; + std::vector data_; }; -class MinStack { - public: - void Push(int value); - int Pop(); - int GetMin(); - - private: - std::vector data_; -}; +#endif \ No newline at end of file diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index 54e7ce90..b557a4c4 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -1,42 +1,54 @@ - #include #include +#include +#include "min_stack.hpp" #include "stack.hpp" TEST(StackTest, Simple) { - Stack stack; - stack.Push(1); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - stack.Push(3); // Stack [1, 3] - ASSERT_EQ(stack.Pop(), 3); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] + Stack stack; + stack.push(1); // Stack [1] + ASSERT_EQ(stack.pop(), 1); // Stack [] + stack.push(1); // Stack [1] + stack.push(2); // Stack [1, 2] + ASSERT_EQ(stack.pop(), 2); // Stack [1] + ASSERT_EQ(stack.pop(), 1); // Stack [] + stack.push(1); // Stack [1] + stack.push(2); // Stack [1, 2] + ASSERT_EQ(stack.pop(), 2); // Stack [1] + stack.push(3); // Stack [1, 3] + ASSERT_EQ(stack.pop(), 3); // Stack [1] + ASSERT_EQ(stack.pop(), 1); // Stack [] } TEST(MinStackTest, Simple) { - MinStack stack; - stack.Push(1); // Stack [1] - ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - stack.Push(3); // Stack [1, 3] - ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 3); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] + MinStack stack; + stack.push(1); // Stack [1] + ASSERT_EQ(stack.getMin(), 1); + ASSERT_EQ(stack.pop(), 1); // Stack [] + stack.push(1); // Stack [1] + stack.push(2); // Stack [1, 2] + ASSERT_EQ(stack.getMin(), 1); + ASSERT_EQ(stack.pop(), 2); // Stack [1] + ASSERT_EQ(stack.pop(), 1); // Stack [] + stack.push(1); // Stack [1] + stack.push(2); // Stack [1, 2] + ASSERT_EQ(stack.getMin(), 1); + ASSERT_EQ(stack.pop(), 2); // Stack [1] + stack.push(3); // Stack [1, 3] + ASSERT_EQ(stack.getMin(), 1); + ASSERT_EQ(stack.pop(), 3); // Stack [1] + ASSERT_EQ(stack.pop(), 1); // Stack [] +} + +TEST(StackTest, empty) { + Stack stack; + ASSERT_THROW(stack.pop(), std::runtime_error); +} + +TEST(MinStackTest, empty) { + MinStack stack; + ASSERT_THROW(stack.getMin(), std::runtime_error); + ASSERT_THROW(stack.pop(), std::runtime_error); } \ No newline at end of file diff --git a/task_03/src/days_till_warming.cpp b/task_03/src/days_till_warming.cpp new file mode 100644 index 00000000..1e432369 --- /dev/null +++ b/task_03/src/days_till_warming.cpp @@ -0,0 +1,14 @@ +#include "days_till_warming.hpp" + +std::vector DaysTillWarming(std::vector temps) { + std::vector days; + std::vector result(temps.size(), 0); + for (size_t i = 0; i < temps.size(); i++) { + while (!days.empty() && (days.back().temp_ < temps[i])) { + result[days.back().id_] = i - days.back().id_; + days.pop_back(); + } + days.push_back(Day(i, temps[i])); + } + return result; +} \ No newline at end of file diff --git a/task_03/src/days_till_warming.hpp b/task_03/src/days_till_warming.hpp new file mode 100644 index 00000000..3d81b735 --- /dev/null +++ b/task_03/src/days_till_warming.hpp @@ -0,0 +1,10 @@ +#include +#include + +struct Day { + Day(size_t id, double temp) : id_{id}, temp_{temp} {} + size_t id_; + double temp_; +}; + +std::vector DaysTillWarming(std::vector temps); \ No newline at end of file diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index ef5a86ae..838174df 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,8 +1,24 @@ #include -#include "topology_sort.hpp" +#include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "days_till_warming.hpp" + +TEST(DaysTillWarming, Simple) { + ASSERT_EQ((DaysTillWarming(std::vector{ + +24, +22, +27, +21, +20, +20, +20, +20, +23, +24, +24, +25, +19, + +19, +22, +28, +21, +21, +22})), + (std::vector{2, 1, 13, 5, 4, 3, 2, 1, 1, 2, 1, 4, 2, 1, 1, + 0, 2, 1, 0})); + ASSERT_EQ((DaysTillWarming(std::vector{-12, -5, -9, 0, +2, +1})), + (std::vector{1, 2, 1, 1, 0, 0})); + ASSERT_EQ((DaysTillWarming(std::vector{0, +1})), + (std::vector{1, 0})); + ASSERT_EQ((DaysTillWarming(std::vector{0})), + (std::vector{0})); } + +TEST(DaysTillWarming, Empty) { + ASSERT_EQ((DaysTillWarming(std::vector{})), (std::vector{})); +} \ No newline at end of file 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..3ad5c7e9 --- /dev/null +++ b/task_04/src/heap.cpp @@ -0,0 +1,2 @@ +// класс шаблонный, но CMake тербует cpp файл +// переписывать CMake не стал, для совместимости \ No newline at end of file diff --git a/task_04/src/heap.hpp b/task_04/src/heap.hpp new file mode 100644 index 00000000..4a19456b --- /dev/null +++ b/task_04/src/heap.hpp @@ -0,0 +1,65 @@ +#ifndef HEAP_HPP +#define HEAP_HPP +#include +#include +#include +#include +#include + +template +class Heap { + public: + Heap() : data_{} {} + + Heap(Heap const& other) : data_{other.data_} {} + + Heap(std::initializer_list data) : data_{data} { + for (size_t i = data_.size() / 2; i; i--) siftDown(i); + siftDown(0); + } + + Heap(std::vector data) : data_{data} { + for (size_t i = data_.size() / 2; i; i--) siftDown(i); + siftDown(0); + } + + Heap const& operator=(Heap const& other) { + data_ = other.data_; + return *(this); + } + + T popMin() { + if (data_.empty()) throw std::runtime_error("can't pop min: heap is empty"); + T result = data_[0]; + data_[0] = data_.back(); + data_.pop_back(); + siftDown(0); + return result; + } + void push(T value) { + data_.push_back(value); + siftUp(data_.size() - 1); + } + + private: + void siftUp(size_t i) { + while (i && data_[i] < data_[(i - 1) / 2]) { + std::swap(data_[i], data_[(i - 1) / 2]); + i = (i - 1) / 2; + } + } + void siftDown(size_t i) { + while ((2 * i + 1) < data_.size()) { + size_t left = 2 * i + 1; + size_t right = 2 * i + 2; + size_t j = left; + if ((right < data_.size()) && (data_[right] < data_[left])) j = right; + if (data_[i] <= data_[j]) break; + std::swap(data_[i], data_[j]); + i = j; + } + } + std::vector data_; +}; + +#endif \ No newline at end of file diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp index 5e11617e..91a1363a 100644 --- a/task_04/src/test.cpp +++ b/task_04/src/test.cpp @@ -1,6 +1,43 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "heap.hpp" + +TEST(Heap, Simple) { + Heap heap; + heap.push(1); + heap.push(2); + heap.push(-1); + ASSERT_EQ(heap.popMin(), -1); + ASSERT_EQ(heap.popMin(), 1); + ASSERT_EQ(heap.popMin(), 2); + heap.push(1); + ASSERT_EQ(heap.popMin(), 1); + heap.push(2); + heap.push(-1); + heap.push(1); + ASSERT_EQ(heap.popMin(), -1); + heap.push(3); + ASSERT_EQ(heap.popMin(), 1); + ASSERT_EQ(heap.popMin(), 2); + ASSERT_EQ(heap.popMin(), 3); } + +TEST(Heap, empty) { + Heap heap; + ASSERT_THROW(heap.popMin(), std::runtime_error); +} + +TEST(Heap, constructor) { + Heap heap = {2, 3, 1, 5, -1}; + ASSERT_EQ(heap.popMin(), -1); + ASSERT_EQ(heap.popMin(), 1); + ASSERT_EQ(heap.popMin(), 2); + std::vector vec = {7, 3, -1, 4}; + Heap heap2 = vec; + ASSERT_EQ(heap2.popMin(), -1); + ASSERT_EQ(heap2.popMin(), 3); + ASSERT_EQ(heap2.popMin(), 4); +} \ No newline at end of file diff --git a/task_05/src/merge_sort.cpp b/task_05/src/merge_sort.cpp new file mode 100644 index 00000000..e69de29b diff --git a/task_05/src/merge_sort.hpp b/task_05/src/merge_sort.hpp new file mode 100644 index 00000000..0e33ae11 --- /dev/null +++ b/task_05/src/merge_sort.hpp @@ -0,0 +1,33 @@ +#ifndef MERGE_SORT_HPP +#define MERGE_SORT_HPP +#include + +template +void merge_sort(std::vector& array) { + if (array.size() > 1) { + std::size_t size = array.size(); + std::size_t const left_size = size / 2; + auto left = std::vector(array.begin(), array.begin() + left_size); + auto right = std::vector(array.begin() + left_size, array.end()); + merge_sort(left); + merge_sort(right); + + std::size_t lidx = 0; + std::size_t ridx = 0; + std::vector tmp_array; + + while (lidx < left.size() || ridx < right.size()) { + if (left[lidx] < right[ridx]) + tmp_array.push_back(left[lidx++]); + else + tmp_array.push_back(right[ridx++]); + if (lidx == left.size()) { + for (; ridx < right.size(); ++ridx) tmp_array.push_back(right[ridx]); + } else if (ridx == right.size()) { + for (; lidx < left.size(); ++lidx) tmp_array.push_back(left[lidx]); + } + } + array = tmp_array; + } +} +#endif \ No newline at end of file diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index 5e11617e..b6845bfd 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -1,6 +1,34 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "merge_sort.hpp" + +TEST(Merge_sort, Simple) { + std::vector data = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + merge_sort(data); + std::vector ref = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + ASSERT_TRUE(data == ref); +} + +TEST(Merge_sort, Unsorted) { + std::vector data = {7, 5, 9, 1, 2, 6, 8, 3, 4}; + merge_sort(data); + std::vector ref = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + ASSERT_TRUE(data == ref); +} + +TEST(Merge_sort, Reversed) { + std::vector data = {9, 8, 7, 6, 5, 4, 3, 2, 1}; + merge_sort(data); + std::vector ref = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + ASSERT_TRUE(data == ref); +} + +TEST(Merge_sort, Empty) { + std::vector data = {}; + merge_sort(data); + std::vector ref = {}; + ASSERT_TRUE(data == ref); } diff --git a/task_06/src/nth_ordinal_statistics.cpp b/task_06/src/nth_ordinal_statistics.cpp new file mode 100644 index 00000000..e69de29b diff --git a/task_06/src/nth_ordinal_statistics.hpp b/task_06/src/nth_ordinal_statistics.hpp new file mode 100644 index 00000000..5665ec0d --- /dev/null +++ b/task_06/src/nth_ordinal_statistics.hpp @@ -0,0 +1,39 @@ +#ifndef NTH_ORDINAL_STATISTIC +#define NTH_ORDINAL_STATISTIC +#include +#include + +template +T nth_ordinal_statistics(std::vector data, size_t k) { + if (data.empty() || k >= data.size()) + throw std::runtime_error("vector is empty"); + for (size_t left = 0, right = data.size();;) { + if (right <= left + 1) { + if (right == left + 1 && data[right] < data[left]) + std::swap(data[left], data[right]); + return data[k]; + } + + size_t mid = (left + right) / 2; + std::swap(data[mid], data[left + 1]); + if (data[left] > data[right]) std::swap(data[left], data[right]); + if (data[left + 1] > data[right]) std::swap(data[left + 1], data[right]); + if (data[left] > data[left + 1]) std::swap(data[left], data[left + 1]); + + size_t i = left + 1, j = right; + const T cur = data[left + 1]; + for (;;) { + while (data[++i] < cur) + ; + while (data[--j] > cur) + ; + if (i > j) break; + std::swap(data[i], data[j]); + } + std::swap(data[left + 1], data[j]); + if (j >= k) right = j - 1; + if (j <= k) left = i; + } +} + +#endif \ No newline at end of file diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 5e11617e..3cdcbd9d 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,6 +1,41 @@ - #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include +#include + +#include "nth_ordinal_statistics.hpp" + +TEST(Nth_ordinal_statistics, Simple) { + std::vector vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + ASSERT_EQ(nth_ordinal_statistics(vec, 1), 1); + ASSERT_EQ(nth_ordinal_statistics(vec, 9), 9); + ASSERT_EQ(nth_ordinal_statistics(vec, 3), 3); + ASSERT_EQ(nth_ordinal_statistics(vec, 5), 5); + ASSERT_EQ(nth_ordinal_statistics(vec, 4), 4); + ASSERT_EQ(nth_ordinal_statistics(vec, 0), 0); + ASSERT_EQ(nth_ordinal_statistics(vec, 8), 8); +} + +TEST(Nth_ordinal_statistics, Unsorted) { + std::vector vec = {9, 2, 3, 0, 7, 1, 6, 4, 8, 5}; + ASSERT_EQ(nth_ordinal_statistics(vec, 0), 0); + ASSERT_EQ(nth_ordinal_statistics(vec, 4), 4); + ASSERT_EQ(nth_ordinal_statistics(vec, 8), 8); +} + +TEST(Nth_ordinal_statistics, Bacwards) { + std::vector vec = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; + ASSERT_EQ(nth_ordinal_statistics(vec, 0), 0); + ASSERT_EQ(nth_ordinal_statistics(vec, 4), 4); + ASSERT_EQ(nth_ordinal_statistics(vec, 8), 8); +} + +TEST(Nth_ordinal_statistics, Empty) { + std::vector vec; + ASSERT_THROW(nth_ordinal_statistics(vec, 0), std::runtime_error); +} + +TEST(Nth_ordinal_statistics, OutOfRange) { + std::vector vec = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + ASSERT_THROW(nth_ordinal_statistics(vec, 12), std::runtime_error); } diff --git a/task_07/CMakeLists.txt b/task_07/CMakeLists.txt index 0e239848..6dfcf2b8 100644 --- a/task_07/CMakeLists.txt +++ b/task_07/CMakeLists.txt @@ -4,7 +4,7 @@ get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) string(REPLACE " " "_" PROJECT_NAME ${PROJECT_NAME}) project(${PROJECT_NAME} C CXX) -set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) file(GLOB_RECURSE source_list "src/*.cpp" "src/*.hpp") diff --git a/task_07/src/binary_tree.hpp b/task_07/src/binary_tree.hpp new file mode 100644 index 00000000..88dec507 --- /dev/null +++ b/task_07/src/binary_tree.hpp @@ -0,0 +1,167 @@ +#ifndef BINARY_TREE_H +#define BINARY_TREE_H +#include + +#include "node.hpp" +namespace s21 { +template +class BinaryTree { + public: + class iterator; + class const_iterator; + + private: + using key_type = Key; + using value_type = Value; + using node = Node; + + std::shared_ptr root = nullptr; + + public: + BinaryTree(std::initializer_list const &items) { + for (auto item : items) node::add(root, item); + } + + BinaryTree() : root{} {} + + BinaryTree(BinaryTree const &other) : root{} { + for (auto i = other.cbegin(); i != other.cend(); i++) node::add(root, *i); + } + + BinaryTree(BinaryTree &&other) : root{other.root} { other.root.reset(); } + + ~BinaryTree() = default; + + BinaryTree const &operator=(BinaryTree &&other) { + // root.reset(); // leacks possible + root = other.root; + other.root.reset(); + return *this; + } + + BinaryTree const &operator=(BinaryTree const &other) { + BinaryTree temp = other; + clear(); + for (auto i = temp.cbegin(); i != temp.cend(); i++) insert(*i); + return *this; + } + + iterator begin() { return iterator{node::begin(root, this)}; } + + iterator end() { return iterator{node::end(root, this)}; } + + const_iterator cbegin() const { + return const_iterator{node::cbegin(root, this)}; + } + + const_iterator cend() const { return const_iterator{node::cend(root, this)}; } + + bool empty() const { return !root; } + + size_t size() const { return node::size(root); } + + size_t max_size() { + std::allocator alloc; + return alloc.max_size() / sizeof(node); + } + + void clear() { root.reset(); } + + std::pair insert(value_type const &key) { + return node::add(root, key, this); + } + + bool erase(key_type const &key) { return bool(node::remove(root, key)); } + + bool erase(iterator const &pos) { + return bool(node::remove(root, pos.__M_iter, this)); + } + + bool erase(const_iterator const &pos) { + return bool(node::remove(root, pos.__M_const_iter, this)); + } + + iterator find(key_type const &key) { return node::find(root, key, this); } + + bool contains(key_type const &key) const { return node::exists(root, key); } +}; + +template +class BinaryTree::iterator { + private: + using node = Node; + using NodeIterator = typename node::NodeIterator; + + public: + NodeIterator __M_iter; + + iterator() = delete; + iterator(NodeIterator const &__M_iter) { this->__M_iter = __M_iter; } + iterator(iterator const &other) { this->__M_iter = other.__M_iter; } + + iterator operator++() { + ++__M_iter; + return *this; + } + iterator operator--() { + --__M_iter; + return *this; + } + iterator operator++(int) { + __M_iter++; + return *this; + } + iterator operator--(int) { + __M_iter--; + return *this; + } + bool operator==(iterator other) { return __M_iter == other.__M_iter; } + bool operator!=(iterator other) { return __M_iter != other.__M_iter; } + Value &operator*() { return *__M_iter; } + Value *operator->() { return __M_iter.operator->(); } +}; + +template +class BinaryTree::const_iterator { + private: + using node = Node; + using ConstNodeIterator = typename node::ConstNodeIterator; + + public: + ConstNodeIterator __M_const_iter; + const_iterator() = delete; + const_iterator(ConstNodeIterator const &__M_const_iter) { + this->__M_const_iter = __M_const_iter; + } + const_iterator(const_iterator const &other) { + this->__M_const_iter = other.__M_const_iter; + } + + const_iterator operator++() { + ++__M_const_iter; + return *this; + } + const_iterator operator--() { + --__M_const_iter; + return *this; + } + const_iterator operator++(int) { + __M_const_iter++; + return *this; + } + const_iterator operator--(int) { + __M_const_iter--; + return *this; + } + bool operator==(const_iterator other) { + return __M_const_iter == other.__M_const_iter; + } + bool operator!=(const_iterator other) { + return __M_const_iter != other.__M_const_iter; + } + Value const &operator*() { return *__M_const_iter; } + Value const *operator->() { return __M_const_iter.operator->(); } +}; + +} // namespace s21 +#endif \ No newline at end of file diff --git a/task_07/src/map.hpp b/task_07/src/map.hpp new file mode 100644 index 00000000..ae253f44 --- /dev/null +++ b/task_07/src/map.hpp @@ -0,0 +1,115 @@ +#ifndef MAP_H +#define MAP_H +#include +#include + +#include "binary_tree.hpp" + +// #include +#include +#include +#include +#include + +namespace s21 { + +template +class map { + private: + static Key const get_key(std::pair pair) { + return pair.first; + } + + private: + using key_type = Key const; + using value_type = std::pair; + using reference = value_type &; + using const_reference = value_type const &; + using binary_tree = BinaryTree::get_key>; + using iterator = typename binary_tree::iterator; + using const_iterator = typename binary_tree::const_iterator; + using size_type = size_t; + + private: + binary_tree tree = nullptr; + + public: + // map(map *map) { this->tree = map->tree; } + map() : tree{} {} + + map(std::initializer_list const &items) : tree{items} {} + + map(const map &s) : tree{s.tree} {} + + map(map &&s) : tree{s.tree} {} + + map const &operator=(map &&s) { + tree.clear(); + tree = s.tree; + s.tree.clear(); + return *this; + } + + map const &operator=(map const &other) { + map temp = other; + tree.clear(); + for (auto i = temp.cbegin(); i != temp.cend(); i++) insert(*i); + return *this; + } + + Data &at(Key const &key) { return tree.find(key)->second; } + + Data &operator[](const Key &key) { return tree.find(key)->second; } + + iterator begin() { return iterator{tree.begin()}; } + + iterator end() { return iterator{tree.end()}; } + + const_iterator cbegin() const { return const_iterator{tree.cbegin()}; } + + const_iterator cend() const { return const_iterator{tree.cend()}; } + + bool empty() { return tree.empty(); } + + size_type size() { return tree.size(); } + + size_type max_size() { return tree.max_size(); } + + void clear() { tree.clear(); } + + std::pair insert(value_type const &key) { + return tree.insert(key); + } + + std::pair insert(const Key &key, const Data &obj) { + return tree.insert(value_type(key, obj)); + } + + std::pair insert_or_assign(const Key &key, const Data &obj) { + auto result = tree.insert(value_type(key, obj)); + if (!(result.second)) result.first->second = obj; + return result; + } + + bool erase(key_type const &key) { return tree.erase(key); } + + bool erase(iterator const &pos) { return tree.erase(pos); } + + bool erase(const_iterator const &pos) { return tree.erase(pos); } + + void swap(map &other) { + auto temp = tree; + tree = other.tree; + other.tree = temp; + } + + void merge(map &other) { + for (auto i = other.begin(); i != other.end(); i++) insert(*i); + } + + bool contains(Key const &key) { return tree.contains(key); } +}; + +} // namespace s21 + +#endif \ No newline at end of file diff --git a/task_07/src/node.hpp b/task_07/src/node.hpp new file mode 100644 index 00000000..4d8ef1a9 --- /dev/null +++ b/task_07/src/node.hpp @@ -0,0 +1,671 @@ +#ifndef NODE_H +#define NODE_H + +// #include +#include +#include +#include +#include + +namespace s21 { + +// template +// concept Comparable = requires(T a, T b) { +// { a < b } -> std::convertible_to; +// { a <= b } -> std::convertible_to; +// { a > b } -> std::convertible_to; +// { a >= b } -> std::convertible_to; +// { a == b } -> std::convertible_to; +// }; + +template +struct Is_comparable { + static constexpr bool is_less = + decltype(std::declval() < std::declval(), std::true_type{})::value; + static constexpr bool is_equal = + decltype(std::declval() == std::declval(), std::true_type{})::value; + static constexpr bool value = is_less && is_equal; +}; + +template +class Node : public std::enable_shared_from_this> { + private: + // static_assert(Comparable::value, "K must be a comparable type"); + static_assert(Is_comparable::value, "K must be a comparable type"); + using node_class = Node; + V value; + std::weak_ptr parent; + std::shared_ptr left_child; + std::shared_ptr right_child; + + public: + class NodeIterator; + class ConstNodeIterator; + + Node(V const &value, std::weak_ptr const &parent) { + this->value = value; + this->parent = parent; + left_child = nullptr; + right_child = nullptr; + if (!parent.expired() && parent.lock() && value < parent.lock()->value) + parent.lock()->left_child = this->shared_from_this(); + else if (!parent.expired() && parent.lock()) + parent.lock()->right_child = this->shared_from_this(); + } + + Node(V const &value_) : value{value_} { + parent.reset(); + left_child = nullptr; + right_child = nullptr; + } + + Node() { + parent.reset(); + left_child = nullptr; + right_child = nullptr; + } + + static NodeIterator begin(std::shared_ptr &root, void *tree) { + auto begin_node = root; + if (begin_node) + while (begin_node->left_child) begin_node = begin_node->left_child; + return NodeIterator(begin_node, tree); + } + + static NodeIterator end(std::shared_ptr &, void *tree) { + return NodeIterator(tree); + } + + static ConstNodeIterator cbegin(std::shared_ptr const &root, + void const *tree) { + auto begin_node = root; + if (begin_node) + while (begin_node->left_child) begin_node = begin_node->left_child; + return ConstNodeIterator(begin_node, tree); + } + + static ConstNodeIterator cend(std::shared_ptr const &, + void const *tree) { + return ConstNodeIterator(tree); + } + + static std::pair add(std::shared_ptr &root, + V const &value, void *tree) { + bool added = push_to_root(root, value); + NodeIterator pos; + if (!added) { + auto parent_pair = parent_for_new_leaf(root, get_key(value)); + auto new_Node_parent = parent_pair.first; + if (parent_pair.second) { + auto leaf = std::shared_ptr(new node_class(value)); + leaf->setParent(new_Node_parent); + added = true; + leaf->balance_up(root); + pos = NodeIterator(leaf, tree); + } else + pos = NodeIterator(new_Node_parent, tree); + } else + pos = NodeIterator(root, tree); + return {pos, added}; + } + + static void add(std::shared_ptr &root, V const &value) { + bool added = push_to_root(root, value); + if (!added) { + auto parent_pair = parent_for_new_leaf(root, get_key(value)); + auto new_Node_parent = parent_pair.first; + if (parent_pair.second) { + auto leaf = std::shared_ptr(new node_class(value)); + leaf->setParent(new_Node_parent); + added = true; + leaf->balance_up(root); + } + } + } + + static bool exists(std::shared_ptr const &root, K const &value) { + return root ? bool(root->findNode(value)) : false; + } + + static NodeIterator find(std::shared_ptr const &root, + K const &key, void *tree) { + NodeIterator pos; + if (root) pos = NodeIterator(root->findNode(key), tree); + return pos; + } + + static std::optional> remove( + std::shared_ptr &root, V const &value) { + std::optional> result = std::nullopt; + if (root) { + auto removing_node = root->findNode(get_key(value)); + if (removing_node) { + result = removing_node->value; + removing_node->delete_node(root); + } + } + return result; + } + + static std::optional> remove( + std::shared_ptr &root, NodeIterator const &pos, + void const *tree) { + std::optional> result = std::nullopt; + if (tree == pos.__M_tree) { + auto removing_node = pos.node; + if (root && !removing_node.expired()) { + result = removing_node.lock()->value; + removing_node.lock()->delete_node(root); + } + } + return result; + } + + static std::optional> remove( + std::shared_ptr &root, ConstNodeIterator const &pos, + void const *tree) { + std::optional> result = std::nullopt; + if (tree == pos.__M_tree) { + auto removing_node = pos.node; + if (root && !removing_node.expired()) { + result = removing_node.lock()->value; + removing_node.lock()->delete_node(root); + } + } + return result; + } + + static size_t size(std::shared_ptr const &root) { + size_t result = 0; + if (root) result = root->size(); + return result; + } + + static size_t height(std::shared_ptr const &root) { + size_t result = 0; + if (root) result = root->height(); + return result; + } + + private: + size_t size() const { + size_t result = 1; + if (left_child) result += left_child->size(); + if (right_child) result += right_child->size(); + return result; + } + + int height() const { + int height_ = 0; + if (left_child) + height_ = left_child->height(); + else + height_ = 0; + if (right_child) height_ = std::max(height_, right_child->height()); + height_++; + return height_; + } + + static bool push_to_root(std::shared_ptr &root, V const &value) { + bool pushed = !root; + if (pushed) root = std::shared_ptr(new node_class(value)); + return pushed; + } + + void balance_up(std::shared_ptr &root) { + std::shared_ptr not_balanced_Node = this->shared_from_this(); + while (not_balanced_Node) { + not_balanced_Node->balance_node(root); + not_balanced_Node = not_balanced_Node->parent.expired() + ? nullptr + : not_balanced_Node->parent.lock(); + } + } + + static std::pair, bool> parent_for_new_leaf( + std::shared_ptr const &root, K const &key) { + std::shared_ptr new_leaf_parent = nullptr; + bool key_is_unique = true; + if (root) { + auto new_leaf_parent_finder = root; + while (!new_leaf_parent && key_is_unique) { + if (key < get_key(new_leaf_parent_finder->value)) { + if (new_leaf_parent_finder->left_child) + new_leaf_parent_finder = new_leaf_parent_finder->left_child; + else + new_leaf_parent = new_leaf_parent_finder; + } else if (get_key(new_leaf_parent_finder->value) < key) { + if (new_leaf_parent_finder->right_child) + new_leaf_parent_finder = new_leaf_parent_finder->right_child; + else + new_leaf_parent = new_leaf_parent_finder; + } else { + new_leaf_parent = new_leaf_parent_finder; + key_is_unique = false; + } + } + } + return {new_leaf_parent, key_is_unique}; + } + + void setParent(std::shared_ptr const &node_parent) { + if (node_parent && get_key(value) < get_key(node_parent->value)) + node_parent->left_child = this->shared_from_this(); + else if (node_parent) + node_parent->right_child = this->shared_from_this(); + parent = node_parent; + } + + std::shared_ptr findNode(K const &key) { + std::shared_ptr node_finder = this->shared_from_this(); + bool found_node = false; + while (node_finder && !found_node) { + if (key < get_key(node_finder->value) && node_finder->left_child) + node_finder = node_finder->left_child; + else if (get_key(node_finder->value) < key && node_finder->right_child) + node_finder = node_finder->right_child; + else if (key == get_key(node_finder->value)) + found_node = true; + else + node_finder = nullptr; + } + return node_finder; + } + + std::shared_ptr tear_biggest_from_least_childs() { + auto changing = this->biggest_from_least_childs(); + if (!changing->parent.expired() && + changing->parent.lock()->left_child == changing) + changing->parent.lock()->left_child = changing->left_child; + else if (!changing->parent.expired()) + changing->parent.lock()->right_child = changing->left_child; + if (changing->left_child) changing->left_child->parent = changing->parent; + return changing; + } + + std::shared_ptr biggest_from_least_childs() { + auto biggest = this->left_child; + while (biggest && biggest->right_child) biggest = biggest->right_child; + return biggest; + } + + std::shared_ptr least_from_biggest_childs() { + auto least = this->right_child; + while (least && least->left_child) least = least->left_child; + return least; + } + + std::shared_ptr tear_least_from_biggest_childs() { + auto changing = this->least_from_biggest_childs(); + if (!changing->parent.expired() && + changing->parent.lock()->left_child == changing) + changing->parent.lock()->left_child = changing->right_child; + else if (!changing->parent.expired()) + changing->parent.lock()->right_child = changing->right_child; + if (changing->right_child) changing->right_child->parent = changing->parent; + return changing; + } + + void replace_node(std::shared_ptr const &replacing_node, + std::shared_ptr &root) { + auto node_to_replace = this->shared_from_this(); + if (!node_to_replace->parent.expired() && node_to_replace->parent.lock()) { + if (node_to_replace->parent.lock()->left_child == node_to_replace) + node_to_replace->parent.lock()->left_child = replacing_node; + else if (!node_to_replace->parent.expired()) + node_to_replace->parent.lock()->right_child = replacing_node; + } else + root = replacing_node; + replacing_node->parent = node_to_replace->parent; + replacing_node->left_child = node_to_replace->left_child; + replacing_node->right_child = node_to_replace->right_child; + if (node_to_replace->left_child) + node_to_replace->left_child->parent = replacing_node; + if (node_to_replace->right_child) + node_to_replace->right_child->parent = replacing_node; + } + + void delete_node(std::shared_ptr &root) { + auto node = this->shared_from_this(); + if (node->left_child) { + auto changing = node->tear_biggest_from_least_childs(); + auto unbalanced_node = + changing->parent.lock() == node ? changing : changing->parent.lock(); + node->replace_node(changing, root); + unbalanced_node->balance_up(root); + } else if (node->right_child) { + auto changing = node->tear_least_from_biggest_childs(); + auto unbalanced_node = + changing->parent.lock() == node ? changing : changing->parent.lock(); + node->replace_node(changing, root); + unbalanced_node->balance_up(root); + } else if (!node->parent.expired()) { + if (node->parent.lock()->left_child == node) + node->parent.lock()->left_child = + nullptr; // node->parent.lock()->left_child.reset(); + else + node->parent.lock()->right_child = + nullptr; // node->parent.lock()->right_child.reset(); + node->parent.lock()->balance_up(root); + } else + root = nullptr; + } + + void balance_node(std::shared_ptr &root) { + int height_left = left_child ? left_child->height() : 0; + int height_right = right_child ? right_child->height() : 0; + if (height_left == height_right + 2) + left_turn(root); + else if (height_right == height_left + 2) + right_turn(root); + } + + void right_turn(std::shared_ptr &root) { + if (right_child->right_child && + (!right_child->left_child || right_child->right_child->height() == + 1 + right_child->left_child->height())) + right_small_turn(root); + else + right_big_turn(root); + } + + void left_turn(std::shared_ptr &root) { + if (left_child->left_child && + (!left_child->right_child || left_child->left_child->height() == + 1 + left_child->right_child->height())) + left_small_turn(root); + else + left_big_turn(root); + } + + void right_big_turn(std::shared_ptr &root) { + // to understand whats shared_A, shared_B, shared_C look up to png in + // images folder + auto shared_A = this->shared_from_this(); + auto shared_B = right_child; + auto shared_C = shared_B->left_child; + if (!shared_A->parent.expired() && + shared_A->parent.lock()->left_child == shared_A) + shared_A->parent.lock()->left_child = shared_C; + else if (shared_A->parent.expired()) + root = shared_C; + else + shared_A->parent.lock()->right_child = shared_C; + shared_C->parent = shared_A->parent; + shared_A->parent = shared_C; + auto temp = shared_C->left_child; + shared_C->left_child = shared_A; + shared_A->parent = shared_C; + shared_A->right_child = temp; + if (temp) temp->parent = shared_A; + temp = shared_C->right_child; + shared_C->right_child = shared_B; + shared_B->parent = shared_C; + shared_B->left_child = temp; + if (temp) temp->parent = shared_B; + } + + void right_small_turn(std::shared_ptr &root) { + auto shared_A = this->shared_from_this(); + auto shared_B = right_child; + if (!shared_A->parent.expired() && + shared_A->parent.lock()->left_child == shared_A) + shared_A->parent.lock()->left_child = shared_B; + else if (shared_A->parent.expired()) + root = shared_B; + else + shared_A->parent.lock()->right_child = shared_B; + shared_B->parent = shared_A->parent; + shared_A->parent = shared_B; + auto temp = shared_B->left_child; + shared_B->left_child = shared_A; + shared_A->right_child = temp; + if (temp) temp->parent = shared_A; + } + + void left_big_turn(std::shared_ptr &root) { + auto shared_A = this->shared_from_this(); + auto shared_B = left_child; + auto shared_C = shared_B->right_child; + if (!shared_A->parent.expired() && + shared_A->parent.lock()->left_child == shared_A) + shared_A->parent.lock()->left_child = shared_C; + else if (shared_A->parent.expired()) + root = shared_C; + else + shared_A->parent.lock()->right_child = shared_C; + shared_C->parent = shared_A->parent; + shared_A->parent = shared_C; + auto temp = shared_C->left_child; + shared_C->left_child = shared_B; + shared_B->parent = shared_C; + shared_B->right_child = temp; + if (temp) temp->parent = shared_B; + temp = shared_C->right_child; + shared_C->right_child = shared_A; + shared_A->parent = shared_C; + shared_A->left_child = temp; + if (temp) temp->parent = shared_A; + } + + void left_small_turn(std::shared_ptr &root) { + auto shared_A = this->shared_from_this(); + auto shared_B = left_child; + if (!shared_A->parent.expired() && + shared_A->parent.lock()->left_child == shared_A) + shared_A->parent.lock()->left_child = shared_B; + else if (shared_A->parent.expired()) + root = shared_B; + else + shared_A->parent.lock()->right_child = shared_B; + shared_B->parent = shared_A->parent; + shared_A->parent = shared_B; + auto temp = shared_B->right_child; + shared_B->right_child = shared_A; + shared_A->left_child = temp; + if (temp) temp->parent = shared_A; + } +}; +template +class Node::NodeIterator { + private: + using node_class = Node; + + public: + std::weak_ptr node; + void *__M_tree; + NodeIterator() { + node.reset(); + __M_tree = nullptr; + } + + NodeIterator(std::weak_ptr node, void *__M_tree) { + this->node = node; + this->__M_tree = __M_tree; + } + + NodeIterator(void *__M_tree) { this->__M_tree = __M_tree; } + + NodeIterator(NodeIterator const &other) { + node = other.node; + __M_tree = other.__M_tree; + } + + NodeIterator const &operator=(NodeIterator const &other) { + node = other.node; + __M_tree = other.__M_tree; + return *this; + } + + V &operator*() { + if (node.expired()) + throw std::runtime_error( + "NodeIterator::operator*(): NodeIterator pointing to nullptr"); + return node.lock()->value; + } + V *operator->() { + if (node.expired()) + throw std::runtime_error( + "NodeIterator::operator->(): NodeIterator pointing to expired value"); + return &(node.lock()->value); + } + + bool operator==(NodeIterator other) { + return (__M_tree == other.__M_tree) && + ((node.expired() && other.node.expired()) || + ((!node.expired() && !other.node.expired()) && + (node.lock() == other.node.lock()))); + } + + bool operator!=(NodeIterator other) { return (!operator==(other)); } + + NodeIterator operator++() { + if (!node.expired()) { + auto node_shared = node.lock(); + if (node_shared->right_child) + node = node_shared->least_from_biggest_childs(); + else { + auto finder = node_shared->parent.expired() + ? nullptr + : node_shared->parent.lock(); + auto finder_child = node_shared; + while (finder && finder->right_child == finder_child) { + finder_child = finder; + finder = finder->parent.expired() ? nullptr : finder->parent.lock(); + } + node = finder; + } + } + return *this; + } + + NodeIterator operator--() { + if (!node.expired()) { + auto node_shared = node.lock(); + if (node_shared->left_child) + node = node_shared->biggest_from_least_childs(); + else { + auto finder = node_shared->parent.expired() + ? nullptr + : node_shared->parent.lock(); + auto finder_child = node_shared; + while (finder && finder->left_child == finder_child) { + finder_child = finder; + finder = finder->parent.expired() ? nullptr : finder->parent.lock(); + } + node = finder; + } + } + + return *this; + } + + NodeIterator operator++(int) { return this->operator++(); } + NodeIterator operator--(int) { return this->operator--(); } +}; + +template +class Node::ConstNodeIterator { + private: + using const_node_class = Node const; + + public: + std::weak_ptr node; + void const *__M_tree; + ConstNodeIterator() { + node.reset(); + __M_tree = nullptr; + } + + ConstNodeIterator(std::weak_ptr node, void const *__M_tree) { + this->node = node; + this->__M_tree = __M_tree; + } + + ConstNodeIterator(void const *__M_tree) { this->__M_tree = __M_tree; } + + ConstNodeIterator(ConstNodeIterator const &other) { + node = other.node; + __M_tree = other.__M_tree; + } + + ConstNodeIterator const &operator=(ConstNodeIterator const &other) { + node = other.node; + __M_tree = other.__M_tree; + return *this; + } + + V const &operator*() { + if (node.expired()) + throw std::runtime_error( + "ConstNodeIterator::operator*(): ConstNodeIterator pointing to " + "nullptr"); + return node.lock()->value; + } + V const *operator->() { + if (node.expired()) + throw std::runtime_error( + "ConstNodeIterator::operator->(): ConstNodeIterator pointing to " + "nullptr"); + return &(node.lock()->value); + } + + bool operator==(ConstNodeIterator other) { + return (__M_tree == other.__M_tree) && + ((node.expired() && other.node.expired()) || + ((!node.expired() && !other.node.expired()) && + (node.lock() == other.node.lock()))); + } + + bool operator!=(ConstNodeIterator other) { return !operator==(other); } + + ConstNodeIterator operator++() { + if (!node.expired()) { + auto node_shared = node.lock(); + if (node_shared->right_child) + node = node_shared->least_from_biggest_childs(); + else { + auto finder = node_shared->parent.expired() + ? nullptr + : node_shared->parent.lock(); + auto finder_child = node_shared; + while (finder && finder->right_child == finder_child) { + finder_child = finder; + finder = finder->parent.expired() ? nullptr : finder->parent.lock(); + } + node = finder; + } + } + return *this; + } + + ConstNodeIterator operator--() { + if (node) { + if (node.expired()) + node.reset(); + else { + auto node_shared = node.lock(); + if (node_shared->left_child) + node = node_shared->biggest_from_least_childs(); + else { + auto finder = node_shared->parent.expired() + ? nullptr + : node_shared->parent.lock(); + auto finder_child = node_shared; + while (finder && finder->left_child == finder_child) { + finder_child = finder; + finder = finder->parent.expired() ? nullptr : finder->parent.lock(); + } + node = finder; + } + } + } + return *this; + } + + ConstNodeIterator operator++(int) { return this->operator++(); } + ConstNodeIterator operator--(int) { return this->operator--(); } +}; + +} // namespace s21 +#endif \ No newline at end of file diff --git a/task_07/src/set.hpp b/task_07/src/set.hpp new file mode 100644 index 00000000..68deced3 --- /dev/null +++ b/task_07/src/set.hpp @@ -0,0 +1,99 @@ +#ifndef SET_H +#define SET_H +#include +#include +#include +#include +#include +#include + +#include "binary_tree.hpp" + + +namespace s21 { + +template +class set { + private: + static Key const get_key(Key const key) { return key; } + + private: + using key_type = Key const; + using value_type = Key const; + using reference = value_type &; + using const_reference = value_type const &; + using binary_tree = BinaryTree::get_key>; + using iterator = typename binary_tree::iterator; + using const_iterator = typename binary_tree::const_iterator; + using size_type = size_t; + + private: + binary_tree tree = nullptr; + + public: + set() : tree{} {} + + set(std::initializer_list const &items) : tree{items} {} + + set(const set &s) : tree{s.tree} {} + + set(set &&s) : tree{s.tree} {} + + set const &operator=(set &&s) { + tree.clear(); + tree = s.tree; + s.tree.clear(); + return *this; + } + + set const &operator=(set const &other) { + set temp = other; + tree.clear(); + for (auto i = temp.cbegin(); i != temp.cend(); i++) insert(*i); + return *this; + } + + iterator begin() { return iterator{tree.begin()}; } + + iterator end() { return iterator{tree.end()}; } + + const_iterator cbegin() const { return const_iterator{tree.cbegin()}; } + + const_iterator cend() const { return const_iterator{tree.cend()}; } + + bool empty() { return tree.empty(); } + + size_type size() { return tree.size(); } + + size_type max_size() { return tree.max_size(); } + + void clear() { tree.clear(); } + + std::pair insert(value_type const &key) { + return tree.insert(key); + } + + bool erase(key_type const &key) { return tree.erase(key); } + + bool erase(iterator const &pos) { return tree.erase(pos); } + + bool erase(const_iterator const &pos) { return tree.erase(pos); } + + void swap(set &other) { + auto temp = tree; + tree = other.tree; + other.tree = temp; + } + + void merge(set &other) { + for (auto i = other.begin(); i != other.end(); i++) insert(*i); + } + + iterator find(key_type const &key) { return tree.find(key); } + + bool contains(key_type const &key) { return tree.contains(key); } +}; + +} // namespace s21 + +#endif \ No newline at end of file diff --git a/task_07/src/test.cpp b/task_07/src/test.cpp index 5e11617e..8cf28462 100644 --- a/task_07/src/test.cpp +++ b/task_07/src/test.cpp @@ -1,6 +1,686 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include +#include + +#include "map.hpp" +#include "set.hpp" + +template +void compare_s21_std_map(s21::map s21map, + std::map stdmap) { + ASSERT_EQ(s21map.size(), stdmap.size()); + auto s21i = s21map.begin(); + auto stdi = stdmap.begin(); + for (; s21i != s21map.end(); s21i++, stdi++) + ASSERT_EQ(s21i->first, stdi->first); } + +template +void compare_s21_std_map(std::map stdmap, + s21::map s21map) { + ASSERT_EQ(s21map.size(), stdmap.size()); + auto s21i = s21map.begin(); + auto stdi = stdmap.begin(); + for (; s21i != s21map.end(); s21i++, stdi++) + ASSERT_EQ(s21i->first, stdi->first); +} + +template +void compare_s21_s21_map(s21::map s21map_1, + s21::map s21map_2) { + ASSERT_EQ(s21map_1.size(), s21map_2.size()); + auto s21_i_1 = s21map_1.begin(); + auto s21_i_2 = s21map_2.begin(); + for (; s21_i_1 != s21map_1.end(); s21_i_1++, s21_i_2++) + ASSERT_EQ(s21_i_1->first, s21_i_2->first); +} + +template +void compare_s21_std_set(s21::set s21set, std::set stdset) { + ASSERT_EQ(s21set.size(), stdset.size()); + auto s21i = s21set.begin(); + auto stdi = stdset.begin(); + for (; s21i != s21set.end(); s21i++, stdi++) ASSERT_EQ(*s21i, *stdi); +} + +template +void compare_s21_std_set(std::set stdset, s21::set s21set) { + ASSERT_EQ(s21set.size(), stdset.size()); + auto s21i = s21set.begin(); + auto stdi = stdset.begin(); + for (; s21i != s21set.end(); s21i++, stdi++) ASSERT_EQ(*s21i, *stdi); +} + +template +void compare_s21_s21_set(s21::set s21set_1, s21::set s21set_2) { + ASSERT_EQ(s21set_1.size(), s21set_2.size()); + auto s21_i_1 = s21set_1.begin(); + auto s21_i_2 = s21set_2.begin(); + for (; s21_i_1 != s21set_1.end(); s21_i_1++, s21_i_2++) + ASSERT_EQ(*s21_i_1, *s21_i_2); +} + +TEST(map, size1) { + s21::map s21map = {}; + ASSERT_EQ(s21map.size(), 0); +} + +TEST(map, size2) { + s21::map s21map = {{1, 1.3}}; + ASSERT_EQ(s21map.size(), 1); +} + +TEST(map, size3) { + s21::map s21map = {{1, 1.3}, {2, 2.3}}; + ASSERT_EQ(s21map.size(), 2); +} + +TEST(map, simple1) { + s21::map s21map = {{1, 1.3}, {2, 2.3}, {3, 3.3}, + {4, 4.3}, {5, 5.3}, {6, 6.3}, + {7, 7.3}, {8, 8.3}, {9, 9.3}}; + std::map stdmap = {{1, 1.3}, {2, 2.3}, {3, 3.3}, + {4, 4.3}, {5, 5.3}, {6, 6.3}, + {7, 7.3}, {8, 8.3}, {9, 9.3}}; + compare_s21_std_map(stdmap, s21map); +} + +TEST(map, simple2) { + s21::map s21map = { + {1, 1.3}, {2, 2.3}, {3, 3.3}, {4, 4.3}, {5, 5.3}, {6, 6.3}, + {7, 7.3}, {8, 8.3}, {9, 9.3}, {1, 1.5}, {2, 2.5}, {3, 3.5}, + {4, 4.3}, {5, 5.3}, {6, 6.5}, {7, 7.5}, {8, 8.5}, {9, 9.5}}; + std::map stdmap = { + {1, 1.3}, {2, 2.3}, {3, 3.3}, {4, 4.3}, {5, 5.3}, {6, 6.3}, + {7, 7.3}, {8, 8.3}, {9, 9.3}, {1, 1.5}, {2, 2.5}, {3, 3.5}, + {4, 4.3}, {5, 5.3}, {6, 6.5}, {7, 7.5}, {8, 8.5}, {9, 9.5}}; + compare_s21_std_map(stdmap, s21map); +} + +TEST(map, simple3) { + s21::map s21map = {{3, 3.3}, {1, 1.3}, {4, 4.3}, + {7, 7.3}, {8, 8.3}, {9, 9.3}, + {5, 5.3}, {6, 6.3}, {2, 2.3}}; + std::map stdmap = {{1, 1.3}, {2, 2.3}, {3, 3.3}, + {4, 4.3}, {5, 5.3}, {6, 6.3}, + {7, 7.3}, {8, 8.3}, {9, 9.3}}; + compare_s21_std_map(stdmap, s21map); +} + +TEST(map, simple4) { + s21::map s21map_orig = {{1, 1.3}, {2, 2.3}, {3, 3.3}, + {4, 4.3}, {5, 5.3}, {6, 6.3}, + {7, 7.3}, {8, 8.3}, {9, 9.3}}; + s21::map s21map_target = s21map_orig; + compare_s21_s21_map(s21map_target, s21map_orig); +} + +TEST(map, simple5) { + s21::map s21map = {{1, 1.3}, {2, 2.3}, {3, 3.3}, + {4, 4.3}, {5, 5.3}, {6, 6.3}, + {7, 7.3}, {8, 8.3}, {9, 9.3}}; + std::map stdmap = {{1, 1.3}, {2, 2.3}, {3, 3.3}, + {4, 4.3}, {5, 5.3}, {6, 6.3}, + {7, 7.3}, {8, 8.3}, {9, 9.3}}; + s21map = s21map; + compare_s21_std_map(stdmap, s21map); +} + +TEST(map, empty1) { + s21::map s21map = {}; + ASSERT_EQ(s21map.empty(), true); +} + +TEST(map, empty2) { + s21::map s21map = {{1, 1.3}}; + ASSERT_EQ(s21map.empty(), false); +} + +TEST(map, clear) { + s21::map s21map = {{1, 1.3}, {2, 2.3}, {3, 3.3}}; + s21map.clear(); + ASSERT_EQ(s21map.empty(), true); +} + +TEST(map, max_size) { + s21::map s21map = {}; + std::map stdmap = {}; + std::cout << "s21 max_size: " << s21map.max_size() << std::endl + << "std max_size: " << stdmap.max_size() << std::endl; + ASSERT_EQ(s21map.empty(), true); +} + +TEST(map, swap) { + s21::map s21map_1 = {{5, 5.3}, {3, 3.3}}; + s21::map s21map_2 = {{7, 7.3}, {8, 8.3}, {9, 9.3}}; + std::map stdmap_1 = {{5, 5.3}, {3, 3.3}}; + std::map stdmap_2 = {{7, 7.3}, {8, 8.3}, {9, 9.3}}; + stdmap_1.swap(stdmap_2); + s21map_1.swap(s21map_2); + compare_s21_std_map(stdmap_1, s21map_1); + compare_s21_std_map(stdmap_2, s21map_2); +} + +TEST(map, merge1) { + s21::map s21map_1 = {{5, 5.3}, {3, 3.3}}; + s21::map s21map_2 = {{7, 7.3}, {8, 8.3}, {9, 9.3}}; + std::map stdmap = { + {5, 5.3}, {3, 3.3}, {7, 7.3}, {8, 8.3}, {9, 9.3}}; + s21map_1.merge(s21map_2); + compare_s21_std_map(s21map_1, stdmap); +} + +TEST(map, merge2) { + s21::map s21map_1 = {{5, 5.3}, {3, 3.3}}; + s21::map s21map_2 = {{7, 7.3}, {8, 8.3}, {9, 9.3}}; + std::map stdmap = { + {5, 5.3}, {3, 3.3}, {7, 7.3}, {8, 8.3}, {9, 9.3}}; + s21map_1.merge(s21map_2); + compare_s21_std_map(s21map_1, stdmap); +} + +TEST(map, insert1) { + s21::map s21map_1 = {{1, 1.3}}; + s21::map s21map_2 = {}; + auto pair = s21map_2.insert({1, 1.3}); + ASSERT_EQ(pair.second, true); + ASSERT_EQ(pair.first->first, 1); + pair = s21map_2.insert({1, 1.5}); + ASSERT_EQ(pair.second, false); + ASSERT_EQ(pair.first->first, 1); + compare_s21_s21_map(s21map_1, s21map_2); +} + +TEST(map, insert2) { + s21::map s21map_1 = {{1, 1.3}, {2, 2.3}, {3, 3.3}, {4, 4.3}, + {5, 5.3}, {6, 6.3}, {7, 7.3}}; + s21::map s21map_2 = {{2, 2.3}, {4, 4.3}, {7, 7.3}}; + s21map_2.insert({3, 3.3}); + s21map_2.insert({4, 4.3}); + s21map_2.insert({3, 3.5}); + s21map_2.insert({2, 2.5}); + s21map_2.insert({5, 5.3}); + s21map_2.insert({7, 7.5}); + s21map_2.insert({6, 6.3}); + auto pair = s21map_2.insert({1, 1.3}); + ASSERT_EQ(pair.second, true); + ASSERT_EQ(pair.first->first, 1); + pair = s21map_2.insert({1, 1.5}); + ASSERT_EQ(pair.second, false); + ASSERT_EQ(pair.first->first, 1); + compare_s21_s21_map(s21map_1, s21map_2); +} + +TEST(map, insert3) { + std::map s21map_1 = { + {0, 0.3}, {-100, -100.3}, {100, 100.3}, {-50, -50.3}, {50, 50.3}, + {-25, -25.3}, {25, 25.3}, {-12, -12.3}, {12, 12.3}, {-6, -6.3}, + {6, 6.3}, {-3, -3.3}, {3, 3.3}, {-1, -1.3}, {1, 1.3}}; + s21::map s21map_2 = {}; + s21map_2.insert({0, 0.3}); + s21map_2.insert({-100, -100.3}); + s21map_2.insert({100, 100.3}); + s21map_2.insert({-50, -50.3}); + s21map_2.insert({50, 50.3}); + s21map_2.insert({-25, -25.3}); + s21map_2.insert({25, 25.3}); + s21map_2.insert({-12, -12.3}); + s21map_2.insert({12, 12.3}); + s21map_2.insert({-6, -6.3}); + s21map_2.insert({6, 6.3}); + s21map_2.insert({-3, -3.3}); + s21map_2.insert({3, 3.3}); + s21map_2.insert({-1, -1.3}); + s21map_2.insert({1, 1.3}); + compare_s21_std_map(s21map_1, s21map_2); +} + +TEST(map, insert4) { + std::map s21map_1 = {{0, 0.3}, {-100, -100.3}, {100, 100.3}, + {-50, -50.3}, {50, 50.3}, {-75, -75.3}, + {75, 75.3}}; + s21::map s21map_2 = {}; + s21map_2.insert({0, 0.3}); + s21map_2.insert({-100, -100.3}); + s21map_2.insert({100, 100.3}); + s21map_2.insert({-50, -50.3}); + s21map_2.insert({50, 50.3}); + s21map_2.insert({-75, -75.3}); + s21map_2.insert({75, 75.3}); + compare_s21_std_map(s21map_1, s21map_2); +} + +TEST(map, insert_or_assign1) { + s21::map s21map_1 = {{1, 1.3}, {2, 2.3}, {3, 3.3}, + {4, 4.3}, {5, 5.3}, {6, 6.3}, + {7, 7.3}, {8, 8.3}, {9, 9.3}}; + s21::map s21map_2 = {{1, 1.5}, {2, 2.5}, {3, 3.5}, + {4, 4.3}, {5, 5.3}, {6, 6.5}, + {7, 7.5}, {8, 8.5}, {9, 9.5}}; + s21::map s21map_target = {}; + s21map_target.insert_or_assign(1, 1.3); + s21map_target.insert_or_assign(2, 2.3); + s21map_target.insert_or_assign(3, 3.3); + s21map_target.insert_or_assign(4, 4.3); + s21map_target.insert_or_assign(5, 5.3); + s21map_target.insert_or_assign(6, 6.3); + s21map_target.insert_or_assign(7, 7.3); + s21map_target.insert_or_assign(8, 8.3); + s21map_target.insert_or_assign(9, 9.3); + compare_s21_s21_map(s21map_1, s21map_target); + s21map_target.insert_or_assign(1, 1.5); + s21map_target.insert_or_assign(2, 2.5); + s21map_target.insert_or_assign(3, 3.5); + s21map_target.insert_or_assign(4, 4.5); + s21map_target.insert_or_assign(5, 5.3); + s21map_target.insert_or_assign(6, 6.5); + s21map_target.insert_or_assign(7, 7.5); + s21map_target.insert_or_assign(8, 8.5); + s21map_target.insert_or_assign(9, 9.5); + compare_s21_s21_map(s21map_1, s21map_target); +} + +TEST(map, erase1) { + s21::map s21map_1 = {}; + s21::map s21map_2 = {{1, 1.3}}; + s21map_2.erase(s21map_2.begin()); + compare_s21_s21_map(s21map_1, s21map_2); +} + +TEST(map, erase2) { + s21::map s21map_1 = {}; + s21::map s21map_2 = {}; + s21map_2.erase(s21map_2.begin()); + compare_s21_s21_map(s21map_1, s21map_2); +} + +TEST(map, erase3) { + std::map stdmap = { + {1, 1.3}, {2, 2.3}, {4, 4.3}, {5, 5.3}, {6, 6.3}}; + s21::map s21map = {{1, 1.3}, {2, 2.3}, {3, 3.3}, + {4, 4.3}, {5, 5.3}, {6, 6.3}}; + auto i = s21map.begin(); + i++; + i++; + s21map.erase(i); + compare_s21_std_map(stdmap, s21map); +} + +TEST(map, at1) { + std::map stdmap = { + {0, 0.3}, {-100, -100.3}, {100, 100.3}, {-50, -50.3}, {50, 50.3}, + {-25, -25.3}, {25, 25.3}, {-12, -12.3}, {12, 12.3}, {-6, -6.3}, + {6, 6.3}, {-3, -3.3}, {3, 3.3}, {-1, -1.3}, {1, 1.3}}; + s21::map s21map = { + {0, 0.3}, {-100, -100.3}, {100, 100.3}, {-50, -50.3}, {50, 50.3}, + {-25, -25.3}, {25, 25.3}, {-12, -12.3}, {12, 12.3}, {-6, -6.3}, + {6, 6.3}, {-3, -3.3}, {3, 3.3}, {-1, -1.3}, {1, 1.3}}; + ASSERT_EQ(stdmap.at(-100), s21map.at(-100)); + ASSERT_EQ(stdmap.at(50), s21map.at(50)); + ASSERT_EQ(stdmap.at(-25), s21map.at(-25)); + ASSERT_EQ(stdmap.at(12), s21map.at(12)); + ASSERT_EQ(stdmap.at(-6), s21map.at(-6)); + ASSERT_EQ(stdmap.at(3), s21map.at(3)); + ASSERT_EQ(stdmap.at(-1), s21map.at(-1)); + ASSERT_EQ(stdmap.at(0), s21map.at(0)); +} + +TEST(map, at2) { + std::map stdmap = {{0, 0.3}, {-100, -100.3}, {100, 100.3}, + {-50, -50.3}, {50, 50.3}, {-75, -75.3}, + {75, 75.3}}; + s21::map s21map = {{0, 0.3}, {-100, -100.3}, {100, 100.3}, + {-50, -50.3}, {50, 50.3}, {-75, -75.3}, + {75, 75.3}}; + ASSERT_EQ(stdmap.at(-100), s21map.at(-100)); + ASSERT_EQ(stdmap.at(50), s21map.at(50)); + ASSERT_EQ(stdmap.at(-75), s21map.at(-75)); + ASSERT_EQ(stdmap.at(0), s21map.at(0)); +} + +TEST(map, at3) { + s21::map s21map = {{0, 0.3}, {-100, -100.3}, {100, 100.3}, + {-50, -50.3}, {50, 50.3}, {-75, -75.3}, + {75, 75.3}}; + ASSERT_ANY_THROW(s21map.at(25)); + EXPECT_ANY_THROW(s21map.at(-25)); + EXPECT_ANY_THROW(s21map.at(10)); +} + +TEST(map, contains1) { + s21::map s21map = { + {0, 0.3}, {-100, -100.3}, {100, 100.3}, {-50, -50.3}, {50, 50.3}, + {-25, -25.3}, {25, 25.3}, {-12, -12.3}, {12, 12.3}, {-6, -6.3}, + {6, 6.3}, {-3, -3.3}, {3, 3.3}, {-1, -1.3}, {1, 1.3}}; + ASSERT_EQ(s21map.contains(-100), true); + ASSERT_EQ(s21map.contains(100), true); + ASSERT_EQ(s21map.contains(-50), true); + ASSERT_EQ(s21map.contains(50), true); + ASSERT_EQ(s21map.contains(-25), true); + ASSERT_EQ(s21map.contains(25), true); + ASSERT_EQ(s21map.contains(-12), true); + ASSERT_EQ(s21map.contains(12), true); + ASSERT_EQ(s21map.contains(-6), true); + ASSERT_EQ(s21map.contains(6), true); + ASSERT_EQ(s21map.contains(-3), true); + ASSERT_EQ(s21map.contains(3), true); + ASSERT_EQ(s21map.contains(-1), true); + ASSERT_EQ(s21map.contains(1), true); + ASSERT_EQ(s21map.contains(0), true); +} + +TEST(map, contains2) { + s21::map s21map = {{0, 0.3}, {-100, -100.3}, {100, 100.3}, + {-50, -50.3}, {50, 50.3}, {-75, -75.3}, + {75, 75.3}}; + ASSERT_EQ(s21map.contains(-100), true); + ASSERT_EQ(s21map.contains(100), true); + ASSERT_EQ(s21map.contains(-50), true); + ASSERT_EQ(s21map.contains(50), true); + ASSERT_EQ(s21map.contains(-75), true); + ASSERT_EQ(s21map.contains(75), true); + ASSERT_EQ(s21map.contains(0), true); +} + +TEST(map, contains3) { + s21::map s21map = {{0, 0.3}, {-100, -100.3}, {100, 100.3}, + {-50, -50.3}, {50, 50.3}, {-75, -75.3}, + {75, 75.3}}; + ASSERT_EQ(s21map.contains(0), true); + ASSERT_EQ(s21map.contains(100), true); + ASSERT_EQ(s21map.contains(-100), true); + ASSERT_EQ(s21map.contains(11), false); + ASSERT_EQ(s21map.contains(-1000), false); + ASSERT_EQ(s21map.contains(1000), false); +} + +TEST(set, size1) { + s21::set s21set = {}; + ASSERT_EQ(s21set.size(), 0); +} + +TEST(set, size2) { + s21::set s21set = {1}; + ASSERT_EQ(s21set.size(), 1); +} + +TEST(set, size3) { + s21::set s21set = {1, 2}; + ASSERT_EQ(s21set.size(), 2); +} + +TEST(set, simple1) { + s21::set s21set = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + std::set stdset = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + compare_s21_std_set(stdset, s21set); +} + +TEST(set, simple2) { + s21::set s21set = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + std::set stdset = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + compare_s21_std_set(stdset, s21set); +} + +TEST(set, simple3) { + s21::set s21set = {3, 1, 4, 7, 8, 9, 5, 6, 2}; + std::set stdset = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + compare_s21_std_set(stdset, s21set); +} + +TEST(set, simple4) { + s21::set s21set_orig = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + s21::set s21set_target = s21set_orig; + compare_s21_s21_set(s21set_target, s21set_orig); +} + +TEST(set, simple5) { + s21::set s21set = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + std::set stdset = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + s21set = s21set; + compare_s21_std_set(stdset, s21set); +} + +TEST(set, empty1) { + s21::set s21set = {}; + ASSERT_EQ(s21set.empty(), true); +} + +TEST(set, empty2) { + s21::set s21set = {1}; + ASSERT_EQ(s21set.empty(), false); +} + +TEST(set, clear) { + s21::set s21set = {1, 2, 3}; + s21set.clear(); + ASSERT_EQ(s21set.empty(), true); +} + +TEST(set, max_size) { + s21::set s21set = {}; + std::set stdset = {}; + std::cout << "s21 max_size: " << s21set.max_size() << std::endl + << "std max_size: " << stdset.max_size() << std::endl; + ASSERT_EQ(s21set.empty(), true); +} + +TEST(set, swap) { + s21::set s21set_1 = {5, 3}; + s21::set s21set_2 = {7, 8, 9}; + std::set stdset_1 = {5, 3}; + std::set stdset_2 = {7, 8, 9}; + stdset_1.swap(stdset_2); + s21set_1.swap(s21set_2); + compare_s21_std_set(stdset_1, s21set_1); + compare_s21_std_set(stdset_2, s21set_2); +} + +TEST(set, merge1) { + s21::set s21set_1 = {5, 3}; + s21::set s21set_2 = {7, 8, 9}; + std::set stdset = {5, 3, 7, 8, 9}; + s21set_1.merge(s21set_2); + compare_s21_std_set(s21set_1, stdset); +} + +TEST(set, merge2) { + s21::set s21set_1 = {5, 3}; + s21::set s21set_2 = {7, 8, 9}; + std::set stdset = {5, 3, 7, 8, 9}; + s21set_1.merge(s21set_2); + compare_s21_std_set(s21set_1, stdset); +} + +TEST(set, insert1) { + s21::set s21set_1 = {1}; + s21::set s21set_2 = {}; + auto pair = s21set_2.insert(1); + ASSERT_EQ(pair.second, true); + ASSERT_EQ(*(pair.first), 1); + pair = s21set_2.insert(1); + ASSERT_EQ(pair.second, false); + ASSERT_EQ(*(pair.first), 1); + compare_s21_s21_set(s21set_1, s21set_2); +} + +TEST(set, insert2) { + s21::set s21set_1 = {1, 2, 3, 4, 5, 6, 7}; + s21::set s21set_2 = {2, 4, 7}; + s21set_2.insert(3); + s21set_2.insert(4); + s21set_2.insert(3); + s21set_2.insert(2); + s21set_2.insert(5); + s21set_2.insert(7); + s21set_2.insert(6); + auto pair = s21set_2.insert(1); + ASSERT_EQ(pair.second, true); + ASSERT_EQ(*(pair.first), 1); + pair = s21set_2.insert(1); + ASSERT_EQ(pair.second, false); + ASSERT_EQ(*(pair.first), 1); + compare_s21_s21_set(s21set_1, s21set_2); +} + +TEST(set, insert3) { + std::set s21set_1 = {0, -100, 100, -50, 50, -25, 25, -12, + 12, -6, 6, -3, 3, -1, 1}; + s21::set s21set_2 = {}; + s21set_2.insert(0); + s21set_2.insert(-100); + s21set_2.insert(100); + s21set_2.insert(-50); + s21set_2.insert(50); + s21set_2.insert(-25); + s21set_2.insert(25); + s21set_2.insert(-12); + s21set_2.insert(12); + s21set_2.insert(-6); + s21set_2.insert(6); + s21set_2.insert(-3); + s21set_2.insert(3); + s21set_2.insert(-1); + s21set_2.insert(1); + compare_s21_std_set(s21set_1, s21set_2); +} + +TEST(set, insert4) { + std::set s21set_1 = {0, -100, 100, -50, 50, -75, 75}; + s21::set s21set_2 = {}; + s21set_2.insert(0); + s21set_2.insert(-100); + s21set_2.insert(100); + s21set_2.insert(-50); + s21set_2.insert(50); + s21set_2.insert(-75); + s21set_2.insert(75); + compare_s21_std_set(s21set_1, s21set_2); +} + +TEST(set, erase1) { + s21::set s21set_1 = {}; + s21::set s21set_2 = {1}; + s21set_2.erase(s21set_2.begin()); + compare_s21_s21_set(s21set_1, s21set_2); +} + +TEST(set, erase2) { + s21::set s21set_1 = {}; + s21::set s21set_2 = {}; + s21set_2.erase(s21set_2.begin()); + compare_s21_s21_set(s21set_1, s21set_2); +} + +TEST(set, erase3) { + std::set stdset = {1, 2, 4, 5, 6}; + s21::set s21set = {1, 2, 3, 4, 5, 6}; + auto i = s21set.begin(); + i++; + i++; + s21set.erase(i); + compare_s21_std_set(stdset, s21set); +} + +TEST(set, find1) { + std::set stdset = {0, -100, 100, -50, 50, -25, 25, -12, + 12, -6, 6, -3, 3, -1, 1}; + s21::set s21set = {0, -100, 100, -50, 50, -25, 25, -12, + 12, -6, 6, -3, 3, -1, 1}; + ASSERT_EQ(*(stdset.find(-100)), *(s21set.find(-100))); + ASSERT_EQ(*(stdset.find(50)), *(s21set.find(50))); + ASSERT_EQ(*(stdset.find(-25)), *(s21set.find(-25))); + ASSERT_EQ(*(stdset.find(12)), *(s21set.find(12))); + ASSERT_EQ(*(stdset.find(-6)), *(s21set.find(-6))); + ASSERT_EQ(*(stdset.find(3)), *(s21set.find(3))); + ASSERT_EQ(*(stdset.find(-1)), *(s21set.find(-1))); + ASSERT_EQ(*(stdset.find(0)), *(s21set.find(0))); +} + +TEST(set, find2) { + std::set stdset = {0, -100, 100, -50, 50, -75, 75}; + s21::set s21set = {0, -100, 100, -50, 50, -75, 75}; + ASSERT_EQ(*(stdset.find(-100)), *(s21set.find(-100))); + ASSERT_EQ(*(stdset.find(50)), *(s21set.find(50))); + ASSERT_EQ(*(stdset.find(-75)), *(s21set.find(-75))); + ASSERT_EQ(*(stdset.find(0)), *(s21set.find(0))); +} + +TEST(set, find3) { + s21::set s21set = {0, -100, 100, -50, 50, -75, 75}; + ASSERT_EQ(s21set.find(25) == s21set.end(), true); + ASSERT_EQ(s21set.find(-25) == s21set.end(), true); + ASSERT_EQ(s21set.find(10) == s21set.end(), true); +} + +TEST(set, contains1) { + s21::set s21set = {0, -100, 100, -50, 50, -25, 25, -12, + 12, -6, 6, -3, 3, -1, 1}; + ASSERT_EQ(s21set.contains(-100), true); + ASSERT_EQ(s21set.contains(100), true); + ASSERT_EQ(s21set.contains(-50), true); + ASSERT_EQ(s21set.contains(50), true); + ASSERT_EQ(s21set.contains(-25), true); + ASSERT_EQ(s21set.contains(25), true); + ASSERT_EQ(s21set.contains(-12), true); + ASSERT_EQ(s21set.contains(12), true); + ASSERT_EQ(s21set.contains(-6), true); + ASSERT_EQ(s21set.contains(6), true); + ASSERT_EQ(s21set.contains(-3), true); + ASSERT_EQ(s21set.contains(3), true); + ASSERT_EQ(s21set.contains(-1), true); + ASSERT_EQ(s21set.contains(1), true); + ASSERT_EQ(s21set.contains(0), true); +} + +TEST(set, contains2) { + s21::set s21set = {0, -100, 100, -50, 50, -75, 75}; + ASSERT_EQ(s21set.contains(-100), true); + ASSERT_EQ(s21set.contains(100), true); + ASSERT_EQ(s21set.contains(-50), true); + ASSERT_EQ(s21set.contains(50), true); + ASSERT_EQ(s21set.contains(-75), true); + ASSERT_EQ(s21set.contains(75), true); + ASSERT_EQ(s21set.contains(0), true); +} + +TEST(set, contains3) { + s21::set s21set = {0, -100, 100, -50, 50, -75, 75}; + ASSERT_EQ(s21set.contains(0), true); + ASSERT_EQ(s21set.contains(100), true); + ASSERT_EQ(s21set.contains(-100), true); + ASSERT_EQ(s21set.contains(11), false); + ASSERT_EQ(s21set.contains(-1000), false); + ASSERT_EQ(s21set.contains(1000), false); +} + +TEST(set, iterator_eq) { + s21::set s21set1 = {0, -100, 100, -50, 50, -75, 75}; + s21::set s21set2 = {0, -100, 100, -50, 50, -75, 75}; + auto iter1 = s21set1.begin(); + auto iter2 = s21set2.begin(); + ASSERT_EQ(s21set1.size(), s21set2.size()); + for (; iter1 != s21set1.end(); ++iter1, ++iter2) { + ASSERT_TRUE(*iter1 == *iter2); + ASSERT_FALSE(iter1 == iter2); + } + ASSERT_FALSE(iter1 == iter2); //указывают на end +} + +TEST(map, iterator_eq) { + s21::map s21map1 = {{0, 0.3}, {-100, -100.3}, {100, 100.3}, + {-50, -50.3}, {50, 50.3}, {-75, -75.3}, + {75, 75.3}}; + s21::map s21map2 = {{0, 0.3}, {-100, -100.3}, {100, 100.3}, + {-50, -50.3}, {50, 50.3}, {-75, -75.3}, + {75, 75.3}}; + auto iter1 = s21map1.begin(); + auto iter2 = s21map2.begin(); + ASSERT_EQ(s21map1.size(), s21map2.size()); + for (; iter1 != s21map1.end(); ++iter1, ++iter2) { + ASSERT_TRUE(*iter1 == *iter2); + ASSERT_FALSE(iter1 == iter2); + } + ASSERT_FALSE(iter1 == iter2); //указывают на end +} \ No newline at end of file diff --git a/task_08/src/hash_table.cpp b/task_08/src/hash_table.cpp new file mode 100644 index 00000000..e69de29b diff --git a/task_08/src/hash_table.hpp b/task_08/src/hash_table.hpp new file mode 100644 index 00000000..dc65e837 --- /dev/null +++ b/task_08/src/hash_table.hpp @@ -0,0 +1,135 @@ +#ifndef HASH_TABLE_HPP +#define HASH_TABLE_HPP +#include + +int HashFunctionHorner(const std::string& s, int table_size, const int key) { + int hash_result = 0; + for (int i = 0; s[i] != s.size(); ++i) + hash_result = (key * hash_result + s[i]) % table_size; + hash_result = (hash_result * 2 + 1) % table_size; + return hash_result; +} +struct HashFunction1 { + int operator()(const std::string& s, int table_size) const { + return HashFunctionHorner(s, table_size, table_size - 1); + } +}; +struct HashFunction2 { + int operator()(const std::string& s, int table_size) const { + return HashFunctionHorner(s, table_size, table_size + 1); + } +}; + +template +class HashTable { + public: + HashTable() { + buffer_size = default_size; + size = 0; + size_all_non_nullptr = 0; + arr = new Node*[buffer_size]; + for (int i = 0; i < buffer_size; ++i) arr[i] = nullptr; + } + ~HashTable() { + for (int i = 0; i < buffer_size; ++i) + if (arr[i]) delete arr[i]; + delete[] arr; + } + void resize() { + int past_buffer_size = buffer_size; + buffer_size *= 2; + size_all_non_nullptr = 0; + size = 0; + Node** arr2 = new Node*[buffer_size]; + for (int i = 0; i < buffer_size; ++i) arr2[i] = nullptr; + std::swap(arr, arr2); + for (int i = 0; i < past_buffer_size; ++i) { + if (arr2[i] && arr2[i]->state) add(arr2[i]->value); + } + for (int i = 0; i < past_buffer_size; ++i) + if (arr2[i]) delete arr2[i]; + delete[] arr2; + } + void rehash() { + size_all_non_nullptr = 0; + size = 0; + Node** arr2 = new Node*[buffer_size]; + for (int i = 0; i < buffer_size; ++i) arr2[i] = nullptr; + std::swap(arr, arr2); + for (int i = 0; i < buffer_size; ++i) { + if (arr2[i] && arr2[i]->state) add(arr2[i]->value); + } + for (int i = 0; i < buffer_size; ++i) + if (arr2[i]) delete arr2[i]; + delete[] arr2; + } + bool find(const T& value, const THash1& hash1 = THash1(), + const THash2& hash2 = THash2()) { + int h1 = hash1(value, buffer_size); + int h2 = hash2(value, buffer_size); + int i = 0; + while (arr[h1] != nullptr && i < buffer_size) { + if (arr[h1]->value == value && arr[h1]->state) return true; + h1 = (h1 + h2) % buffer_size; + ++i; + } + return false; + } + bool remove(const T& value, const THash1& hash1 = THash1(), + const THash2& hash2 = THash2()) { + int h1 = hash1(value, buffer_size); + int h2 = hash2(value, buffer_size); + int i = 0; + while (arr[h1] != nullptr && i < buffer_size) { + if (arr[h1]->value == value && arr[h1]->state) { + arr[h1]->state = false; + --size; + return true; + } + h1 = (h1 + h2) % buffer_size; + ++i; + } + return false; + } + bool add(const T& value, const THash1& hash1 = THash1(), + const THash2& hash2 = THash2()) { + if (size + 1 > int(rehash_size * buffer_size)) + resize(); + else if (size_all_non_nullptr > 2 * size) + rehash(); + int h1 = hash1(value, buffer_size); + int h2 = hash2(value, buffer_size); + int i = 0; + int first_deleted = -1; + while (arr[h1] != nullptr && i < buffer_size) { + if (arr[h1]->value == value && arr[h1]->state) return false; + if (!arr[h1]->state && first_deleted == -1) first_deleted = h1; + h1 = (h1 + h2) % buffer_size; + ++i; + } + if (first_deleted == -1) { + arr[h1] = new Node(value); + ++size_all_non_nullptr; + } else { + arr[first_deleted]->value = value; + arr[first_deleted]->state = true; + } + ++size; + return true; + } + + private: + static const int default_size = 8; + constexpr static const double rehash_size = 0.75; + struct Node { + T value; + bool state; + Node(const T& value_) : value(value_), state(true) {} + }; + Node** arr; + int size; + int buffer_size; + int size_all_non_nullptr; +}; + +#endif \ No newline at end of file diff --git a/task_08/src/test.cpp b/task_08/src/test.cpp index 5e11617e..4d4e7d25 100644 --- a/task_08/src/test.cpp +++ b/task_08/src/test.cpp @@ -1,6 +1,20 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "hash_table.hpp" + +TEST(HashTable, Simple) { + HashTable table; + table.add("qwert"); + table.add("niyaz"); + ASSERT_EQ(table.find("niyaz"), true); + ASSERT_EQ(table.find("qwert"), true); + ASSERT_EQ(table.find("aaaaaaaa"), false); +} + +TEST(HashTable, Empty) { + HashTable table; + ASSERT_EQ(table.find("qwert"), false); } diff --git a/task_09/src/money_to_coins.cpp b/task_09/src/money_to_coins.cpp new file mode 100644 index 00000000..bb5c5601 --- /dev/null +++ b/task_09/src/money_to_coins.cpp @@ -0,0 +1,11 @@ +#include "money_to_coins.hpp" + +size_t MoneyToCoins(size_t money, std::vector coins) { + if (coins.empty()) throw std::runtime_error("there is no coins"); + std::vector table(money + 1, std::numeric_limits::max()); + table[0] = 0; + for (size_t i = 1; i <= money; ++i) + for (size_t j : coins) + if (j <= i) table[i] = std::min(table[i], table[i - j] + 1); + return table[money]; +} \ No newline at end of file diff --git a/task_09/src/money_to_coins.hpp b/task_09/src/money_to_coins.hpp new file mode 100644 index 00000000..7675d831 --- /dev/null +++ b/task_09/src/money_to_coins.hpp @@ -0,0 +1,7 @@ +#ifndef MONEY_TO_COINS_HPP +#define MONEY_TO_COINS_HPP +#include +#include +#include +size_t MoneyToCoins(size_t money, std::vector coins); +#endif \ No newline at end of file diff --git a/task_09/src/test.cpp b/task_09/src/test.cpp index 869094dd..7249e650 100644 --- a/task_09/src/test.cpp +++ b/task_09/src/test.cpp @@ -1,4 +1,21 @@ #include -TEST(TopologySort, Simple) { ASSERT_EQ(1, 1); } +#include +#include + +#include "money_to_coins.hpp" + +TEST(MoneyToCoins, Simple) { + ASSERT_EQ(MoneyToCoins(14, std::vector{1, 2, 5, 10}), 3); + ASSERT_EQ(MoneyToCoins(19, std::vector{1, 2, 5, 10}), 4); + ASSERT_EQ(MoneyToCoins(15, std::vector{1, 7, 10}), 3); + ASSERT_EQ(MoneyToCoins(14, std::vector{1, 7, 10}), 2); + ASSERT_EQ(MoneyToCoins(21, std::vector{1, 7, 10}), 3); + ASSERT_EQ(MoneyToCoins(34, std::vector{1, 7, 10}), 4); +} + +TEST(MoneyToCoins, Empty) { + ASSERT_THROW(MoneyToCoins(14, std::vector{}), std::runtime_error); + ASSERT_EQ(MoneyToCoins(0, std::vector{1, 2, 5, 10}), 0); +} \ No newline at end of file