diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 0000000..230c749 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1,2 @@ +service_name: github +repo_token: ZRdiHKTOaRoRIWGWShUwUJx499MHpc4XL diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e6b73cb --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,70 @@ +{ + "files.associations": { + "iostream": "cpp", + "vector": "cpp", + "xstring": "cpp", + "stdexcept": "cpp", + "algorithm": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "format": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "locale": "cpp", + "memory": "cpp", + "new": "cpp", + "optional": "cpp", + "ostream": "cpp", + "set": "cpp", + "sstream": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "utility": "cpp", + "xfacet": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp", + "array": "cpp", + "deque": "cpp", + "ranges": "cpp", + "span": "cpp", + "stack": "cpp", + "chrono": "cpp", + "forward_list": "cpp", + "ratio": "cpp", + "random": "cpp", + "list": "cpp" + } +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b09a83..0f42bdd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,16 +2,41 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) # название проекта -project(Algorithms-and-Data-Structures) +project(Ans) + +# Добавление флагов компиляции для покрытия +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage") + +if(MSVC) + add_compile_options(/utf-8) # Для Visual Studio (MSVC) +else() + add_compile_options(-finput-charset=UTF-8 -fexec-charset=UTF-8) # Для GCC/Clang +endif() # затем следует список инструкций для подключения проектов из подкаталогов include(cmake/function.cmake) # подхватываем функции, реализованные в файле function.cmake # для простоты мы объединили наборы команд для создания статической библиотеки - # и для создания исполняемого проекта в отдельные функции - + # и для создания исполняемого проекта в отдельные функции +add_subdirectory(lib_pair) add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main +add_subdirectory(lib_dmassive) +add_subdirectory(lib_stack) +add_subdirectory(lib_vector) +add_subdirectory(lib_queue) +add_subdirectory(lib_list) +add_subdirectory(lib_check_brackets) +add_subdirectory(lib_stack_list) +add_subdirectory(lib_polinom) +add_subdirectory(lib_matrix) +add_subdirectory(lib_dsu) +add_subdirectory(lib_merge_sorted_lists) +add_subdirectory(lib_itable) +add_subdirectory(lib_tbsttable) +add_subdirectory(lib_bin_search_tree) +add_subdirectory(lib_heap) +add_subdirectory(lib_avl) option(BTEST "build test?" ON) # указываем подключаем ли google-тесты (ON или YES) или нет (OFF или NO) @@ -19,3 +44,13 @@ if(BTEST) # если тесты подключены add_subdirectory(gtest) # подключаем дополнительный CMakeLists.txt из подкаталога с именем gtest add_subdirectory(tests) # подключаем дополнительный CMakeLists.txt из подкаталога с именем test endif() + +# Добавление цели для генерации отчета о покрытии +add_custom_target(coverage + COMMAND ${CMAKE_COMMAND} -E remove_directory coverage + COMMAND mkdir -p coverage + COMMAND lcov --capture --directory . --output-file coverage.info + COMMAND genhtml coverage.info --output-directory coverage + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + DEPENDS my_tests +) diff --git a/gtest/gtest-all.cc b/gtest/gtest-all.cc index ff9e512..735343d 100644 --- a/gtest/gtest-all.cc +++ b/gtest/gtest-all.cc @@ -9589,4 +9589,4 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames( #endif // GTEST_HAS_TYPED_TEST_P } // namespace internal -} // namespace testing +} // namespace testing \ No newline at end of file diff --git a/gtest/gtest.h b/gtest/gtest.h index 6e7cfc2..3f6168a 100644 --- a/gtest/gtest.h +++ b/gtest/gtest.h @@ -20060,4 +20060,4 @@ inline int RUN_ALL_TESTS() { return ::testing::UnitTest::GetInstance()->Run(); } -#endif // GTEST_INCLUDE_GTEST_GTEST_H_ +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ \ No newline at end of file diff --git a/lib_avl/CMakeLists.txt b/lib_avl/CMakeLists.txt new file mode 100644 index 0000000..d58f223 --- /dev/null +++ b/lib_avl/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(AVL) \ No newline at end of file diff --git a/lib_avl/avl.cpp b/lib_avl/avl.cpp new file mode 100644 index 0000000..4ca5079 --- /dev/null +++ b/lib_avl/avl.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_avl/avl.h" diff --git a/lib_avl/avl.h b/lib_avl/avl.h new file mode 100644 index 0000000..3a0dd51 --- /dev/null +++ b/lib_avl/avl.h @@ -0,0 +1,236 @@ +#ifndef LIB_AVL_TREE_H_ +#define LIB_AVL_TREE_H_ + +#include +#include +#include +#include "../lib_avl/avl_node.h" +template +class AVLTree { + AVLNode* root; + void clear(AVLNode* node); + AVLNode* insert(AVLNode* node , T key); + AVLNode* remove(AVLNode* node,T key ); + bool search(const AVLNode* node,T key ) const ; + AVLNode* rightRotate(AVLNode* node); + AVLNode* leftRotate(AVLNode* node); + AVLNode* min_value_node(AVLNode* node); + int height(AVLNode* node) const; + int balance(AVLNode* node) const; + public: + AVLTree() : root(nullptr) {} + + ~AVLTree(); + + void insert(T key); + + void remove(T key); + bool search(T key) const; + AVLNode* getRoot() const { + return root; + } +}; +template +bool AVLTree:: search(T key) const { return search(root, key); } +template +void AVLTree::clear(AVLNode* node) { + if (node) { + clear(node->left); + clear(node->right); + delete node; + } +} +template +AVLTree::~AVLTree() { + clear(root); +} +template +AVLNode* AVLTree::insert(AVLNode* node , T key){ + if(node == nullptr){ + return new AVLNode(key); + } + if(key < node->key) { + node ->left = insert(node ->left , key); + } + else if(key > node->key) { + node->right= insert(node->right, key); + } + else { + throw std::invalid_argument("double key: "); + } + node->height = 1 + (std::max(height(node->left) , height(node->right))); + int balanceFactor = balance(node); + if(balanceFactor > 1 && key < node->left->key){ + return rightRotate(node); + // B A + // / \ / \ + // A C D B + // / \ > / / \ + // D E X E C + // \ + // X + } + if(balanceFactor < -1 && key > node->right->key){ + return leftRotate(node); + // A B + // / \ / \ + // C B A E + // / \ > / \ / + // D E C D X + // \ + // X + } + if(balanceFactor > 1 && key > node->left->key){ + node->left = leftRotate(node->left); + return rightRotate(node); + // C C B + // / \ / \ / \ + // A L B L A C + // / \ > / \ > / \ / \ + // D B A F D E F L + // / \ / \ / + // E F D E X + // / / + // X X + } + if((balanceFactor < -1 )&& key < node->right->key){ + node->right = rightRotate(node->right); + return leftRotate(node); + // A (balance=-2) A B + // / \ / \ / \ + // K C (disbalanced) K B (new right) A C + // / \ => / \ => / \ / \ + // B E D C K D F E + // / \ / \ / + // D F F E X + // / / + // X X + } + return node; +} +template +void AVLTree::insert(T key) { + root = insert(root, key); +} +template +AVLNode* AVLTree::remove(AVLNode* node,T key ){ + if (!node) { + throw std::out_of_range("Ключ не найден: "); + } + if (key < node->key) { + node->left = remove(node->left, key); + } else if (key > node->key) { + node->right = remove(node->right, key); + } else { + if ((node->left == nullptr) || (node->right == nullptr)) { + AVLNode* temp = node->left ? node->left : node->right; + if (temp == nullptr) { + temp = node; + node = nullptr; + } else { + *node = *temp; + } + delete temp; + } else { + AVLNode* temp = min_value_node(node->right); + node->key = temp->key; + node->right = remove(node->right, temp->key); + } + } + + if (node == nullptr) { + return node; + } + + node->height = 1 + std::max(height(node->left), height(node->right)); + if (balance(node) > 1 && balance(node->left) >= 0) { + return rightRotate(node); + } + if (balance(node) > 1 && balance(node->left) < 0) { + node->left = leftRotate(node->left); + return rightRotate(node); + } + if (balance(node) < -1 && balance(node->right) <= 0) { + return leftRotate(node); + } + if (balance(node) < -1 && balance(node->right) > 0) { + node->right = rightRotate(node->right); + return leftRotate(node); + } + + return node; +} +template +void AVLTree::remove(T key) { + root = remove(root, key); +} +template +bool AVLTree::search(const AVLNode* node, T key) const { + if (!node) return false; + if (key == node->key) return true; + return key < node->key ? search(node->left, key) : search(node->right, key); +} + +template +AVLNode* AVLTree::rightRotate(AVLNode* B ){ + // A B + // / / \ + // B > C A + // / \ / + // C D D + if (!B || !B->left) { + throw std::logic_error("Невозможно выполнить правый поворот"); + } + AVLNode* A = B->left; + AVLNode* D = A->right; + A->right = B; + B->left =D; + B->height = std::max(height(B->left), height(B->right)) + 1; + A->height = std::max(height(A->left),height(A->right)) + 1; + return A; +} +template +AVLNode* AVLTree::leftRotate(AVLNode* A){ + // A B + // \ / \ + // B > A D + // / \ \ + // C D C + if (!A || !A->right) { + throw std::logic_error("Невозможно выполнить левый поворот"); + } + AVLNode* B = A->right; + AVLNode* C = B->left; + B->left = A; + A->right = C; + A->height = std::max(height(A->left),height(A->right)) + 1; + B->height= std::max(height(B->left),height(B->right)) + 1; + return B; +} + +template +AVLNode* AVLTree::min_value_node(AVLNode* node){ + if (!node) { + throw std::invalid_argument("Узел не существует"); + } + AVLNode* current = node; + while (current->left) { + current = current->left; + } + return current; +} +template +int AVLTree:: height(AVLNode* node) const{ + if(node == nullptr){ + return 0; + } + return node ->height; +} +template +int AVLTree:: balance(AVLNode* node) const{ + if(node == nullptr) { + return 0; + } + return height(node->left) - height(node->right); +} +#endif // LIB_AVL_TREE_H_ \ No newline at end of file diff --git a/lib_avl/avl_node.cpp b/lib_avl/avl_node.cpp new file mode 100644 index 0000000..5c455d1 --- /dev/null +++ b/lib_avl/avl_node.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_avl/avl_node.h" diff --git a/lib_avl/avl_node.h b/lib_avl/avl_node.h new file mode 100644 index 0000000..75a41a0 --- /dev/null +++ b/lib_avl/avl_node.h @@ -0,0 +1,21 @@ +#ifndef LIB_AVL_NODE_H_ +#define LIB_AVL_NODE_H_ + +#include +#include +template +class AVLNode { + public: + T key; + AVLNode* left; + AVLNode* right; + int height; + AVLNode(T k); +}; +template +AVLNode:: AVLNode(T k) + : key(k) + , left(nullptr) + , right(nullptr) + , height(1) {} +#endif // LIB_AVL_NODE_H_ \ No newline at end of file diff --git a/lib_bin_search_tree/CMakeLists.txt b/lib_bin_search_tree/CMakeLists.txt new file mode 100644 index 0000000..996ee7f --- /dev/null +++ b/lib_bin_search_tree/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(BinSearchTree) \ No newline at end of file diff --git a/lib_bin_search_tree/bin_search_tree.cpp b/lib_bin_search_tree/bin_search_tree.cpp new file mode 100644 index 0000000..d8cfe81 --- /dev/null +++ b/lib_bin_search_tree/bin_search_tree.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_bin_search_tree/bin_search_tree.h" diff --git a/lib_bin_search_tree/bin_search_tree.h b/lib_bin_search_tree/bin_search_tree.h new file mode 100644 index 0000000..b64629c --- /dev/null +++ b/lib_bin_search_tree/bin_search_tree.h @@ -0,0 +1,247 @@ +#ifndef LIB_TBIN_SEARCH_TREE_H_ +#define LIB_TBIN_SEARCH_TREE_H_ + +#include +#include +#include // Для std::move + +template +class TBinSearchTree { + // Узел дерева + struct Node { + Key key; // Ключ + Value value; // Значение + Node* left; // Левый потомок + Node* right; // Правый потомок + Node* parent; // Родитель + + // Конструктор узла + Node(const Key& k, const Value& v) + : key(k), value(v), left(nullptr), right(nullptr), parent(nullptr) {} + + // Альтернативный конструктор для семантики перемещения + Node(const Key& k, Value&& v) + : key(k), value(std::move(v)), left(nullptr), right(nullptr), parent(nullptr) {} + }; + + Node* root = nullptr; // Корень дерева + +public: + // Конструктор по умолчанию + TBinSearchTree() = default; + + // Деструктор (очищает память) + ~TBinSearchTree() { + clear(root); + } + + // Конструктор копирования + TBinSearchTree(const TBinSearchTree& other) { + copyTree(root, other.root, nullptr); + } + + // Оператор присваивания + TBinSearchTree& operator=(const TBinSearchTree& other) { + if (this != &other) { + clear(root); + copyTree(root, other.root, nullptr); + } + return *this; + } + + // Основные операции + Node* search(const Key& key) const; // Поиск по ключу + void insert(const Key& key, const Value& value); // Вставка (копирование значения) + void insert(const Key& key, Value&& value); // Вставка (перемещение значения) + void remove(const Key& key); // Удаление по ключу + Node* minimum() const; // Минимальный элемент + Node* maximum() const; // Максимальный элемент + bool isEmpty() const { return root == nullptr; } // Проверка на пустоту + +private: + // Вспомогательные методы + Node* minimum(Node* node) const; // Поиск минимума в поддереве + Node* maximum(Node* node) const; // Поиск максимума в поддереве + void removeNode(Node* node); // Удаление узла + Node* findNode(const Key& key) const; // Поиск узла по ключу + void copyTree(Node*& newNode, const Node* oldNode, Node* parent); // Копирование дерева + void clear(Node* node); // Очистка дерева +}; + +template +void TBinSearchTree::copyTree(Node*& newNode, const Node* oldNode, Node* parent) { + if (oldNode == nullptr) { + newNode = nullptr; + return; + } + + newNode = new Node(oldNode->key, oldNode->value); + newNode->parent = parent; + copyTree(newNode->left, oldNode->left, newNode); + copyTree(newNode->right, oldNode->right, newNode); +} + +template +void TBinSearchTree::clear(Node* node) { + if (node != nullptr) { + clear(node->left); + clear(node->right); + delete node; + } +} + +template +typename TBinSearchTree::Node* TBinSearchTree::minimum(Node* node) const { + if (node == nullptr) return nullptr; + while (node->left != nullptr) node = node->left; + return node; +} + +template +typename TBinSearchTree::Node* TBinSearchTree::minimum() const { + return minimum(root); +} + +template +typename TBinSearchTree::Node* TBinSearchTree::maximum(Node* node) const { + if (node == nullptr) return nullptr; + while (node->right != nullptr) node = node->right; + return node; +} + +template +typename TBinSearchTree::Node* TBinSearchTree::maximum() const { + return maximum(root); +} + +template +typename TBinSearchTree::Node* TBinSearchTree::search(const Key& key) const { + Node* current = root; + while (current != nullptr) { + if (key == current->key) return current; + current = key < current->key ? current->left : current->right; + } + return nullptr; +} + +template +void TBinSearchTree::insert(const Key& key, const Value& value) { + if (root == nullptr) { + root = new Node(key, value); + return; + } + + Node* parent = nullptr; + Node* current = root; + + while (current != nullptr) { + parent = current; + if (key < current->key) { + current = current->left; + } else if (key > current->key) { + current = current->right; + } else { + // Ключ уже существует, обновляем значение + current->value = value; + return; + } + } + + Node* newNode = new Node(key, value); + newNode->parent = parent; + if (key < parent->key) { + parent->left = newNode; + } else { + parent->right = newNode; + } +} + +template +void TBinSearchTree::insert(const Key& key, Value&& value) { + if (root == nullptr) { + root = new Node(key, std::move(value)); + return; + } + + Node* parent = nullptr; + Node* current = root; + + while (current != nullptr) { + parent = current; + if (key < current->key) { + current = current->left; + } else if (key > current->key) { + current = current->right; + } else { + // Ключ уже существует, перемещаем значение + current->value = std::move(value); + return; + } + } + + Node* newNode = new Node(key, std::move(value)); + newNode->parent = parent; + if (key < parent->key) { + parent->left = newNode; + } else { + parent->right = newNode; + } +} + +template +typename TBinSearchTree::Node* TBinSearchTree::findNode(const Key& key) const { + return search(key); +} + +template +void TBinSearchTree::removeNode(Node* node) { + if (node == nullptr) return; + + // Случай 1: Узел без детей + if (node->left == nullptr && node->right == nullptr) { + if (node->parent != nullptr) { + if (node->parent->left == node) { + node->parent->left = nullptr; + } else { + node->parent->right = nullptr; + } + } else { + root = nullptr; + } + delete node; + } + // Случай 2: Узел с одним ребенком + else if (node->left == nullptr || node->right == nullptr) { + Node* child = (node->left != nullptr) ? node->left : node->right; + + if (node->parent != nullptr) { + if (node->parent->left == node) { + node->parent->left = child; + } else { + node->parent->right = child; + } + child->parent = node->parent; + } else { + root = child; + child->parent = nullptr; + } + delete node; + } + // Случай 3: Узел с двумя детьми + else { + Node* successor = minimum(node->right); + node->key = successor->key; + node->value = std::move(successor->value); + removeNode(successor); + } +} + +template +void TBinSearchTree::remove(const Key& key) { + Node* nodeToDelete = findNode(key); + if (nodeToDelete != nullptr) { + removeNode(nodeToDelete); + } +} + +#endif // LIB_TBIN_SEARCH_TREE_H_ \ No newline at end of file diff --git a/lib_bin_search_tree/bin_tree.cpp b/lib_bin_search_tree/bin_tree.cpp new file mode 100644 index 0000000..5d8f381 --- /dev/null +++ b/lib_bin_search_tree/bin_tree.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_bin_search_tree/bin_tree.h" diff --git a/lib_bin_search_tree/bin_tree.h b/lib_bin_search_tree/bin_tree.h new file mode 100644 index 0000000..70bff5d --- /dev/null +++ b/lib_bin_search_tree/bin_tree.h @@ -0,0 +1,111 @@ +/* #ifndef LIB_TBIN_TREE_H_ +#define LIB_TBIN_TREE_H_ + +#include +#include +#include // для std::max +template +class TBinSearchTree; +template +class TreeNode { + friend class TBinSearchTree; + T value; // Значение узла + TreeNode* left; // Левый потомок + TreeNode* right; // Правый потомок + TreeNode* parent; + +public: + // Конструктор по умолчанию + TreeNode() : left(nullptr), right(nullptr) {} + + // Основной конструктор + TreeNode(T value, TreeNode* left = nullptr, TreeNode* right = nullptr) + : value(value), left(left), right(right) {} + + // Конструктор копирования + TreeNode(const TreeNode& node); + + // Деструктор (очищаем память) + ~TreeNode() { + delete left; + delete right; + } + + // Получить значение узла + T get_value() const { return value; } + + // Получить левого потомка + TreeNode* get_left_node() const { return left; } + + // Получить правого потомка + TreeNode* get_right_node() const { return right; } + + // Высота левого поддерева + int get_left_height() const; + + // Высота правого поддерева + int get_right_height() const; + + TreeNode* get_uncle() const; + // Оператор присваивания + TreeNode& operator=(const TreeNode& node); +}; + +// Реализация конструктора копирования +template +TreeNode::TreeNode(const TreeNode& node) + : value(node.value), left(nullptr), right(nullptr) { + if (node.left) left = new TreeNode(*node.left); + if (node.right) right = new TreeNode(*node.right); +} + +// Реализация вычисления высоты левого поддерева +template +int TreeNode::get_left_height() const { + if (!left) return 0; + return 1 + std::max(left->get_left_height(), left->get_right_height()); +} + +// Реализация вычисления высоты правого поддерева +template +int TreeNode::get_right_height() const { + if (!right) return 0; + return 1 + std::max(right->get_left_height(), right->get_right_height()); +} +template +TreeNode* TreeNode::get_uncle() const { + if (!parent) { + return nullptr; + } + if (!parent->parent) { + return nullptr; + } + + // Если родитель является левым потомком дедушки, то дядя - правый потомок дедушки + if (parent == parent->parent->left) { + return parent->parent->right; + } + // Иначе дядя - левый потомок дедушки + else { + return parent->parent->left; + } +} +// Реализация оператора присваивания +template +TreeNode& TreeNode::operator=(const TreeNode& node) { + if (this != &node) { + // Очищаем старые потомки + delete left; + delete right; + + // Копируем значение + value = node.value; + + // Копируем потомков (если они есть) + left = node.left ? new TreeNode(*node.left) : nullptr; + right = node.right ? new TreeNode(*node.right) : nullptr; + } + return *this; +} + +#endif // LIB_TBIN_TREE_H_ */ \ No newline at end of file diff --git a/lib_check_brackets/CMakeLists.txt b/lib_check_brackets/CMakeLists.txt new file mode 100644 index 0000000..5845b8d --- /dev/null +++ b/lib_check_brackets/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(CheckBrackets) \ No newline at end of file diff --git a/lib_check_brackets/check_brackets.cpp b/lib_check_brackets/check_brackets.cpp new file mode 100644 index 0000000..1e774cf --- /dev/null +++ b/lib_check_brackets/check_brackets.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_check_brackets/check_brackets.h" diff --git a/lib_check_brackets/check_brackets.h b/lib_check_brackets/check_brackets.h new file mode 100644 index 0000000..b52a1f8 --- /dev/null +++ b/lib_check_brackets/check_brackets.h @@ -0,0 +1,65 @@ +#ifndef LIB_CHECKBRACKETS_CHECKBRACKETS_H_ +#define LIB_CHECKBRACKETS_CHECKBRACKETS_H_ + +#include +#include +#include +#include + +class TCheckBrackets { +private: + std::string _data; +public: + TCheckBrackets(const std::string& data); + ~TCheckBrackets(); + bool areBracketsBalanced(); +}; + +TCheckBrackets::TCheckBrackets(const std::string& data) : _data(data) { +} + +TCheckBrackets::~TCheckBrackets() { +} + +bool TCheckBrackets::areBracketsBalanced() { + std::stack s; + char x; + for (size_t i = 0; i < _data.size(); i++) { + if (_data[i] == '(' || _data[i] == '[' || _data[i] == '{') { + s.push(_data[i]); + continue; + } + + if (s.empty()) + return false; + + switch (_data[i]) { + case ')': + x = s.top(); + s.pop(); + if (x == '{' || x == '[') + return false; + break; + + case '}': + + x = s.top(); + s.pop(); + if (x == '(' || x == '[') + return false; + break; + + case ']': + + x = s.top(); + s.pop(); + if (x == '(' || x == '{') + return false; + break; + } + } + + return (s.empty()); +} + +#endif // LIB_CHECKBRACKETS_CHECKBRACKETS_H_ diff --git a/lib_dmassive/CMakeLists.txt b/lib_dmassive/CMakeLists.txt new file mode 100644 index 0000000..77c9135 --- /dev/null +++ b/lib_dmassive/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(DMassive) \ No newline at end of file diff --git a/lib_dmassive/archive.cpp b/lib_dmassive/archive.cpp new file mode 100644 index 0000000..4672bef --- /dev/null +++ b/lib_dmassive/archive.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_dmassive/archive.h" diff --git a/lib_dmassive/archive.h b/lib_dmassive/archive.h new file mode 100644 index 0000000..e14cce1 --- /dev/null +++ b/lib_dmassive/archive.h @@ -0,0 +1,638 @@ +// Copyright 2024 Anvar +#pragma once +#include +#include +#include +#define STEP_CAPACITY 15 +#define MAX_CAPACITY 100000 + +enum State { empty, busy, deleted }; + +namespace algorithm { +template +inline void swap(T& val_1, T& val_2) noexcept { + T tmp = val_1; + val_1 = val_2; + val_2 = tmp; +} +} + +template +class TDMassive { + T* _data; + State* _states; + size_t _capacity; + size_t _size; + size_t _deleted; + + public: + + TDMassive(); + TDMassive(const TDMassive& archive); + TDMassive(const T* arr, size_t n); + TDMassive(size_t n, T value); + TDMassive(const TDMassive& archive, size_t pos, size_t n); + explicit TDMassive(size_t n); + + ~TDMassive(); + + void print() const noexcept; + + inline bool empty() const noexcept; + inline bool full() const noexcept; + + size_t size() const noexcept; + size_t capacity() const noexcept; + State get_state(size_t index) const; + + void set_size(size_t size) noexcept; + const T* data() const; + + void swap(TDMassive& archive); + + TDMassive& assign(const TDMassive& archive); + + void clear(); + void resize(size_t n, T value = NULL); + void reserve(size_t n = 15); + + void push_back(T value); // добавление элемента (в конец) + void pop_back(); // удаление элемента (из конца) + void push_front(T value); // добавление элемента (в начало) + void pop_front(); // удаление элемента (из начала) + TDMassive& insert(const T* arr, size_t n, size_t pos); + TDMassive& insert(T value, size_t pos); + + TDMassive& replace(size_t pos, T new_value); + + TDMassive& erase(size_t pos, size_t n); + TDMassive& remove_all(T value); + TDMassive& remove_first(T value); + TDMassive& remove_last(T value); + TDMassive& remove_by_index(size_t pos); + + size_t* find_all(T value) const noexcept; + size_t find_first(T value) const; + size_t find_last(T value) const; + + T& operator[](size_t index); + const T& operator[](size_t index) const; + TDMassive& operator=(const TDMassive& other); + State getState(size_t index) const; + size_t getDeletedCount() const; + private: + size_t count_value(T value) const noexcept; + void repacking(); +}; + + +template +TDMassive::TDMassive() { + _size = 0; + _capacity = STEP_CAPACITY; + _data = new T[_capacity]; + _states = new State[_capacity]; + for (size_t i = 0; i < STEP_CAPACITY; i++) { + _states[i] = State::empty; + } +} +template +TDMassive ::TDMassive(const TDMassive& archive) : +_size(archive._size) , _capacity(archive._capacity), _deleted(archive._deleted) { + _data = new T[_capacity]; + _states = new State[_capacity]; + if(archive._states[0] == State::deleted){ + for (size_t i = 0; i < _size - 1; i++) { + _data[i] = archive._data[i + 1]; + _states[i] = archive._states[i + 1]; + } + _size--; + } else { + for (size_t i = 0; i < _size; ++i) { + _data[i] = archive._data[i]; + _states[i] = archive._states[i]; + } + } + for (size_t i = _size; i < _capacity; ++i) { + _states[i] = State::empty; + } + +} +template +TDMassive::TDMassive(const T* arr, size_t n): +_size(n) , _capacity((n > STEP_CAPACITY) ? n : STEP_CAPACITY), _deleted(0) { + _data = new T[_capacity]; + _states = new State[_capacity]; + + for (size_t i = 0; i < _size; i++) { + _data[i] = arr[i]; + _states[i] = State::busy; + } + for (size_t i = _size; i < _capacity; i++) { + _states[i] = State::empty; + } + + +} +template +TDMassive::TDMassive(size_t n, T value) : + _size(n), _capacity((n > STEP_CAPACITY) ? n : STEP_CAPACITY), _deleted(0) { + if (n == 0) { + _data = nullptr; + _states = nullptr; + } + else { + _data = new T[_capacity]; + _states = new State[_capacity]; + for (size_t i = 0; i < _size; i++) { + _data[i] = value; + _states[i] = State::busy; + } + for (size_t i = _size; i < _capacity; i++) { + _states[i] = State::empty; + } + } +} +template +TDMassive::TDMassive(const TDMassive& archive, size_t pos, size_t n): + _size(n), _capacity((n > STEP_CAPACITY) ? n : STEP_CAPACITY) { + if (pos + n > archive._size) { + throw std::out_of_range("invalid"); + } + _data = new T[_capacity]; + _states = new State[_capacity]; + + for (size_t i = 0; i < _capacity; i++) { + _data[i] = archive._data[pos + i]; + _states[i] = archive._states[pos + i]; + } + for (size_t i = n; i < _capacity; i++) { + _states[i] = State::empty; + } +} +template +TDMassive::TDMassive(size_t n) : _size(0), _capacity(n), _deleted(0) { + _data = new T[_capacity]; + _states = new State[_capacity]; + for (size_t i = 0; i < _capacity; i++) { + _states[i] = State::empty; + } + if (_states[0] == State::deleted) { + ++_deleted; + --_size; + } +} + +template +TDMassive::~TDMassive() { + delete[] _data; + delete[] _states; + _data = nullptr; +} + +template +inline bool TDMassive::empty() const noexcept { + return _size == 0; +} + +template +inline bool TDMassive::full() const noexcept { + return _size == _capacity; +} +template +size_t TDMassive::size() const noexcept { + return _size; +} + +template +size_t TDMassive::capacity() const noexcept { + return _capacity; + +} +template +const T* TDMassive::data() const { + +/* if (_states[0] == State::busy) { + for (size_t i = _size; i > 0; i--) { + _data[i] = _data[i - 1]; + _states[i] = _states[i - 1]; + } + return _data; + } */ + /* if(_states[0] == State::busy){ + for (size_t i = _size; i > 0; --i) { + _data[i] = _data[i - 1]; + _states[i] = _states[i - 1]; + } + } */ + return _data; +} +template +void TDMassive::swap(TDMassive& archive) { + std::swap(_data, archive._data); + std::swap(_states, archive._states); + std::swap(_capacity, archive._capacity); + std::swap(_size, archive._size); + std::swap(_deleted, archive._deleted); +} +template +TDMassive& TDMassive:: assign(const TDMassive& archive) { + if (this != &archive) { + delete[] _data; + delete[] _states; + + _capacity = archive._capacity; + _size = archive._size; + _deleted = archive._deleted; + + _data = new T[_capacity]; + _states = new State[_capacity]; + + for (size_t i = 0; i < _capacity; i++) { + _data[i] = archive._data[i]; + _states[i] = archive._states[i]; + } + } + + return *this; +} +template +void TDMassive::clear() { + _size = 0; + _deleted = 0; + for (size_t i = 0; i < _capacity; i++) { + _states[i] = State::empty; + } +} +template +void TDMassive::resize(size_t n, T value) { + if (n > _capacity) { + T* new_data = new T[n]; + State* new_states = new State[n]; + for (size_t i = 0; i < _size; i++) { + new_data[i] = _data[i]; + new_states[i] = _states[i]; + } + + for (size_t i = _size; i < n; i++) { + new_data[i] = value; + new_states[i] = State::busy; + + + } + + if (_data) { + delete[] _data; + _data = nullptr; + } + if (_states) { + delete[] _states; + _states = nullptr; + } + _data = new_data; + _states = new_states; + _capacity = n; + }else { + for (size_t i = _size; i < n; i++) { + _data[i] = value; + _states[i] = State::busy; + } + } + _size = n; +} +template +void TDMassive::reserve(size_t n) { + if (n > _capacity) { + T* new_data = new T[n];// написать формулу со step capacity + State* new_states = new State[n]; + for (size_t i = 0; i < _size; i++) { + new_data[i] = _data[i]; + new_states[i] = _states[i]; + + } + delete[] _data; + delete[] _states; + _data = new_data; + _states = new_states; + _capacity = n; + } +} +template +void TDMassive::push_back(T value){ + if (_size == -1) { + throw std::out_of_range("masive is full"); + } + if (this->full()) { + reserve(_capacity + 1); + } + + _data[_size] = value; + _states[_size] = State::busy; + _size++; + +} +template +void TDMassive::pop_back() { + if (_size <= 0) { + throw std::logic_error("Error in function" \ + "TDMassive& insert(const T* arr, size_t n, size_t pos)\":" + " wrong position value."); + } + else{ + _states[_size - 1] = State::empty; + _size--; + } +} +template +void TDMassive::pop_front() { + if (_size - _deleted <= 0) { + throw std::logic_error("Error in function" \ + "TDMassive& insert(const T* arr, size_t n, size_t pos)\":" + " wrong position value."); + } + if (_size == -1) { + throw std::out_of_range("masive is full"); + } + for (size_t i = 0; i < _size; i++) { + if (_states[i] != State::deleted) { + _states[i] = State::deleted; + break; + } + } + _deleted++; + _size--; +} +template +void TDMassive::push_front(T value) { + if (this->full()) { + reserve(_capacity + STEP_CAPACITY); + } + if (_size == -1) { + throw std::out_of_range("masive is full"); + } + for (size_t i = _size; i > 0; i--) { + _data[i] = _data[i - 1]; + _states[i] = _states[i - 1]; + } + _data[0] = value; + _states[0] = State::busy; + _size++; +} + +template +TDMassive& TDMassive::insert(const T* arr, size_t n, size_t pos) { + if (_size < pos) { + throw std::logic_error("Error in function \ +\"TDMassive& insert(T value, size_t pos)\": wrong position value."); + } + if (_size + n > _capacity) { + reserve(_capacity + n); + } + for (size_t i = _size; i > pos; --i) { + _data[i + n - 1] = _data[i - 1]; + _states[i + n - 1] = _states[i - 1]; + } + for (size_t i = 0; i < n; ++i) { + _data[pos + i] = arr[i]; + _states[pos + i] = State::busy; + } + _size += n; + return *this; +} +template +TDMassive& TDMassive::insert(T value, size_t pos) { + if (_size < pos) { + throw std::logic_error("Error in function \ +\"TDMassive& insert(T value, size_t pos)\": wrong position value."); + } + if (this->full()) { + size_t newCapacity = _capacity + STEP_CAPACITY; + if (newCapacity < _capacity) { + throw std::overflow_error("Maximum capacity reached."); + } + this->reserve(newCapacity); + } + for (size_t i = _size; i > pos; i--) { + _data[i] = _data[i - 1]; + _states[i] = _states[i - 1]; + } + _data[pos] = value; + _states[pos] = State::busy; + _size++; + + return *this; +} +template +TDMassive& TDMassive::replace(size_t pos, T new_value) { + if (_size <= pos) { + throw std::logic_error("Error in function \ +\"TDMassive& insert(T value, size_t pos)\": wrong position value."); + } + if (this->full()) { + size_t newCapacity = _capacity + STEP_CAPACITY; + if (newCapacity < _capacity) { + throw std::overflow_error("Maximum capacity reached."); + } + this->reserve(newCapacity); + } + _data[pos] = new_value; + _states[pos] = State::busy; + return *this; + +} +template +TDMassive& TDMassive::erase(size_t pos, size_t n) { + if (pos >= _size || pos + n > _size) { + throw std::out_of_range("Error in function \"TDMassive& erase(size_t pos, size_t n)\": position or range out of bounds."); + } + for (size_t i = pos; i < pos + n; ++i) { + _states[i] = State::deleted; + } + for (size_t i = pos + n; i < _size; ++i) { + _data[i - n] = _data[i]; + _states[i - n] = _states[i]; + } + _size -= n; + return *this; +} +template +TDMassive& TDMassive::remove_all(T value) { + size_t shift = 0; + + for (size_t i = 0; i < _size; ++i) { + if (_data[i] == value) { + _states[i] = State::deleted; + ++shift; + } + else if (shift > 0) { + _data[i - shift] = _data[i]; + _states[i - shift] = _states[i]; + } + } + + _size -= shift; + return *this; +} +template +TDMassive& TDMassive::remove_first(T value) { + size_t index = _size; + for (size_t i = 0; i < _size; i++) { + if (_data[i] == value) { + index = i; + break; + } + } + if (index < _size) { + for (size_t i = index; i < _size - 1; i++) { + _data[i] = _data[i + 1]; + } + _size--; + _states[_size] = State::deleted; + } + return *this; +} +template +TDMassive& TDMassive::remove_last(T value) { + for (size_t i = _size; i >= 1; --i) { + if (_data[i - 1] == value) { + _states[i - 1] = State::deleted; + for (size_t j = i - 1; j < _size;++j) { + _data[j] = _data[j + 1]; + _states[j] = _states[j + 1]; + } + _size--; + break; + } + } + return *this; +} +template +TDMassive& TDMassive::remove_by_index(size_t pos) { + if (pos >= _size) { + throw std::out_of_range("Index out of range"); + } + _states[pos] = State::deleted; + for (size_t i = pos; i < _size - 1; ++i) { + _data[i] = _data[i + 1]; + _states[i] = _states[i + 1]; + } + _size--; + return *this; +} +template +void TDMassive::print() const noexcept { + for (size_t i = 0; i < _size; i++) { + if (_states[i] != State::deleted) { + std::cout << _data[i] << ", "; + } + } +} + +template +size_t* TDMassive::find_all(T value) const noexcept { + size_t count = this->count_value(value); + if (count == 0) { + return nullptr; + } + size_t* found_positions = new size_t[count + 1]; + found_positions[0] = count; + size_t found_count = 0; + + for (size_t i = 0; i < _size; ++i) { + if (_data[i] == value && _states[i] != State::deleted) { + found_positions[++found_count] = i; + } + } + + return found_positions; +} +template +size_t TDMassive::find_first(T value) const{ + for (size_t i = 0; i < _size; i++) { + if (_data[i] == value && _states[i] != State::deleted) { + return i; + } + } + return -1; + + } + + +template +size_t TDMassive::find_last(T value) const { + for (size_t i = _size; i > 0; i--) { + if (_data[i] == value && _states[i] != State::deleted) { + return i; + } + } + return -1; +} +template +State TDMassive::getState(size_t index) const { + return _states[index]; +} +template +size_t TDMassive::count_value(T value) const noexcept { + size_t count = 0; + for (size_t i = 0; i < _size; i++) { + if (_data[i] == value && _states[i] != State::deleted) { + count++; + } + } + return count; +} +template +size_t TDMassive::getDeletedCount() const { + size_t count = 0; + for (size_t i = 0; i < _size; ++i) { + if (_states[i] == State::deleted) { + ++count; + } + } + return count; +} +template +T& TDMassive::operator[](size_t index) { + if (index >= _size) { + throw std::out_of_range("Индекс выходит за пределы массива"); + } + for (size_t i = index; i < _size; i++){ + if(_states[i] == State::busy ){ + return _data[i]; + } + } + throw std::out_of_range("Элемент не найден"); +} + +template +const T& TDMassive::operator[](size_t index) const { + if (index >= _size) { + throw std::out_of_range("Индекс выходит за пределы массива"); + } + for (size_t i = index; i < _size; i++){ + if(_states[i] == State::busy ){ + return _data[i]; + } + } + throw std::out_of_range("Элемент не найден"); +} +template +TDMassive& TDMassive::operator=(const TDMassive& other) { + if (this != &other) { + delete[] _data; + delete[] _states; + _size = other._size; + _capacity = other._capacity; + _deleted = other._deleted; + _data = new T[_capacity]; + _states = new State[_capacity]; + for (size_t i = 0; i < _size; i++) { + _data[i] = other._data[i]; + _states[i] = other._states[i]; + } + } + return *this; +} + + + diff --git a/lib_dsu/CMakeLists.txt b/lib_dsu/CMakeLists.txt new file mode 100644 index 0000000..45b8a62 --- /dev/null +++ b/lib_dsu/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(Dsu) \ No newline at end of file diff --git a/lib_dsu/dsu.cpp b/lib_dsu/dsu.cpp new file mode 100644 index 0000000..f8b8590 --- /dev/null +++ b/lib_dsu/dsu.cpp @@ -0,0 +1,3 @@ +// Copyright 2024 Anvar +#include "../lib_dsu/dsu.h" + diff --git a/lib_dsu/dsu.h b/lib_dsu/dsu.h new file mode 100644 index 0000000..6b0b299 --- /dev/null +++ b/lib_dsu/dsu.h @@ -0,0 +1,85 @@ +#ifndef DSU_H +#define DSU_H + +#include + +template +class DSU { + + int _size; + int *_parent; + int *_rank; + +public: + DSU(int size = 0); + ~DSU(); + void make_set(int elem); + int find(int elem); + void union_sets(int first, int second); + void clear(); + +}; + +template +DSU::DSU(int size) : _size(size), _parent(new int[size]), _rank(new int[size]) { + for (int i = 0; i < size; ++i) { + _parent[i] = i; + _rank[i] = 1; + } +} + +template +DSU::~DSU() { + delete[] _parent; + delete[] _rank; +} + +template +void DSU::make_set(int elem) { + if (elem >= 0 && elem < _size) { + _parent[elem] = elem; + _rank[elem] = 1; + } +} + +template +int DSU::find(int elem) { + if (elem < 0 || elem >= _size) { + throw std::logic_error("Element out of range"); + } + + if (_parent[elem] != elem) { + _parent[elem] = find(_parent[elem]); + } + return _parent[elem]; +} + +template +void DSU::union_sets(int first, int second) { + int first_root = find(first); + int second_root = find(second); + + if (first_root == -1 || second_root == -1 || first_root == second_root) { + return; + } + + if (_rank[first_root] < _rank[second_root]) { + _parent[first_root] = second_root; + } else { + _parent[second_root] = first_root; + if (_rank[first_root] == _rank[second_root]) { + _rank[first_root]++; + } + } +} + +template +void DSU::clear() { + delete[] _parent; + delete[] _rank; + _parent = nullptr; + _rank = nullptr; + _size = 0; +} + +#endif // DSU_H \ No newline at end of file diff --git a/lib_heap/CMakeLists.txt b/lib_heap/CMakeLists.txt new file mode 100644 index 0000000..cb9cd00 --- /dev/null +++ b/lib_heap/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(Heap) \ No newline at end of file diff --git a/lib_heap/heap.cpp b/lib_heap/heap.cpp new file mode 100644 index 0000000..c796c24 --- /dev/null +++ b/lib_heap/heap.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_heap/heap.h" diff --git a/lib_heap/heap.h b/lib_heap/heap.h new file mode 100644 index 0000000..4b2706d --- /dev/null +++ b/lib_heap/heap.h @@ -0,0 +1,190 @@ +#ifndef LIB_KUCHA_H_ +#define LIB_KUCHA_H_ + +#include +#include + +#include "../lib_vector/vector.h" +template +class Heap { +private: + T* _data; // Динамический массив для хранения элементов + size_t _capacity; // Текущая вместимость кучи + size_t _size; // Количество элементов в куче + +public: + + void resize(size_t new_capacity); + void heapify_up(size_t index); + void heapify_down(size_t index); + size_t parent(size_t index) const; + size_t left_child(size_t index) const; + size_t right_child(size_t index) const; + + Heap(); + explicit Heap(size_t initial_capacity); + Heap(const Heap& other); + Heap(Heap&& other) noexcept; + ~Heap(); + bool compare(const T& a, const T& b) const { // Компаратор для min/max кучи + return isMinHeap ? (a < b) : (a > b); + } + + void push_heap(const T& value); + void pop_heap(); + void emplace(size_t index, const T& value); + + const T& top() const; + inline bool is_empty() const noexcept; + + +}; + +template +size_t Heap::parent(size_t index) const{ + if (index == 0) { + return 0; + } + return ((index - 1) / 2); +} +template +size_t Heap::left_child(size_t index) const{ + return 2 * index + 1; +} +template +size_t Heap::right_child(size_t index) const{ + return 2 * index + 2; +} +template +void Heap::resize(size_t new_capacity) { + if (new_capacity < _size) new_capacity = _size; + if (new_capacity == _capacity) return; + + T* new_data = new T[new_capacity]; + std::move(_data, _data + _size, new_data); + delete[] _data; + + _data = new_data; + _capacity = new_capacity; +} +template +void Heap:: heapify_up(size_t index){ + while (index > 0 && compare(_data[index], _data[parent(index)])){ + std::swap(_data[index], _data[parent(index)] ); + index = parent(index); + } +} +template +void Heap:: heapify_down(size_t index){ + size_t or_index = index; + if(left_child(index) < _size && compare(_data[left_child(index)] , _data[or_index])){ + or_index = left_child(index); + } + if(right_child(index) < _size && compare(_data[right_child(index)], _data[or_index])){ + or_index = right_child(index); + } + if(index != or_index) { + std::swap(_data[index] , _data[or_index]); + heapify_down(or_index); + } +} +template +Heap::Heap() + : _capacity(10), + _size(0), + _data(new T[_capacity]) +{} +// Конструктор с параметром начальной вместимости +template +Heap::Heap(size_t initial_capacity = 10) + : _capacity(initial_capacity), _size(0) { + if (_capacity < 1) { + _capacity = 1; // Минимальная вместимость + } + _data = new T[_capacity]; +} + +// Конструктор копирования +template +Heap::Heap(const Heap& other) + : _capacity(other._capacity), _size(other._size) { + _data = new T[_capacity]; + for (size_t i = 0; i < _size; ++i) { + _data[i] = other._data[i]; + } +} + +// Конструктор перемещения +template +Heap::Heap(Heap&& other) noexcept + : _data(other._data), _capacity(other._capacity), _size(other._size) { + other._data = nullptr; + other._capacity = 0; + other._size = 0; +} + +// Деструктор +template +Heap::~Heap() { + delete[] _data; +} + +template +void Heap:: push_heap(const T& value){ + if(_size == _capacity){ + resize(_capacity * 2); + } + _data[_size] = value; + + heapify_up(_size); + _size ++; +} +template +void Heap:: pop_heap(){ + if (_size == 0) { + throw std::out_of_range("Heap is empty"); + } + // перемещаем последний элемент в корень + _data[0] = _data[_size - 1]; + _size--; + + // перестраиваем кучу, если она не пуста + if (_size > 0) { + heapify_down(0); + } + +} +template +void Heap:: emplace(size_t index, const T& value){ + if (index >= _capacity) { + throw std::out_of_range("Index exceeds heap capacity"); + } + + if (index < _size) { + _data[index] = value; + if (index > 0 && compare(_data[index], _data[parent(index)])) { + heapify_up(index); + } else { + heapify_down(index); + } + } else if (index == _size) { + push_heap(value); + } else { + throw std::logic_error(" index > size"); + } +} + +template +const T& Heap:: top() const{ + if (_size == 0) { + throw std::out_of_range("Heap is empty"); + } + return _data[0]; +} +template +inline bool Heap::is_empty() const noexcept { + return _size == 0; +} + + +#endif // LIB_KUCHA_H_ \ No newline at end of file diff --git a/lib_heap/max_heap.h b/lib_heap/max_heap.h new file mode 100644 index 0000000..3e814dd --- /dev/null +++ b/lib_heap/max_heap.h @@ -0,0 +1,49 @@ + +#ifndef LIB_MAX_HEAP_H_ +#define LIB_MAX_HEAP_H_ + +#include +#include +template +class MaxHeap { + TVal* _data; + size_t _capacity, _size; + public: + MaxHeap(size_t size = 0); + MaxHeap(size_t size, const TVal* arr); +/* … */ + inline size_t left(size_t size) const; + inline size_t right(size_t) const; + inline size_t parent(size_t) const; + inline bool is_empty() const noexcept; + void insert(TVal) noexcept; + // void erase(size_t); + void emplace(size_t, TVal); + inline TVal max() const; + TVal remove_max(); + private: + void max_heapify() noexcept; + void sift_down(size_t) noexcept; + void sift_up(size_t) noexcept; +}; + +template +MaxHeap::MaxHeap(size_t size = 0){ + _capacity = size; + _data = new TVal[_capacity]; + +} +template +MaxHeap::MaxHeap(size_t size, const TVal* arr){ + _capacity = size; + _data = new TVal[_capacity] + for(size_t i = 0; i < _size; i++){ + _data[i] = arr[i] + } + +} +template +inline MaxHeap:: size_t left(size_t size){ + +} +#endif // LIB_MAX_HEAP_H_ \ No newline at end of file diff --git a/lib_heap/min_heap.h b/lib_heap/min_heap.h new file mode 100644 index 0000000..e69de29 diff --git a/lib_itable/CMakeLists.txt b/lib_itable/CMakeLists.txt new file mode 100644 index 0000000..a217d7e --- /dev/null +++ b/lib_itable/CMakeLists.txt @@ -0,0 +1,3 @@ +create_project_lib(Itable) +add_depend(StackList List lib_list) +add_depend(Stack Pair lib_pair) \ No newline at end of file diff --git a/lib_itable/itable.cpp b/lib_itable/itable.cpp new file mode 100644 index 0000000..decfc8d --- /dev/null +++ b/lib_itable/itable.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_itable/itable.h" diff --git a/lib_itable/itable.h b/lib_itable/itable.h new file mode 100644 index 0000000..f623f07 --- /dev/null +++ b/lib_itable/itable.h @@ -0,0 +1,23 @@ +#ifndef LIB_ITABLE_H_ +#define LIB_ITABLE_H_ + +#include +#include +#include "../lib_list/list.h" +#include "../lib_pair/pair.h" + +template +class ITable { +public: + virtual ~ITable() = default; + virtual void Insert(const TKey& key) = 0; + virtual void Insert(const TKey& key, const TVal& val) = 0; + virtual void Remove(const TKey& key) = 0; + virtual TVal* Find(const TKey& key) = 0; // Возвращает указатель на значение + + virtual size_t Size() const = 0; + virtual bool IsEmpty() const = 0; + virtual TList>& Items() = 0; // Основная строка с ошибкой +}; + +#endif // LIB_ITABLE_H_ \ No newline at end of file diff --git a/lib_itable/unsorted_table.cpp b/lib_itable/unsorted_table.cpp new file mode 100644 index 0000000..1306acb --- /dev/null +++ b/lib_itable/unsorted_table.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_itable/unsorted_table_list.h" diff --git a/lib_itable/unsorted_table_list.h b/lib_itable/unsorted_table_list.h new file mode 100644 index 0000000..bbd2492 --- /dev/null +++ b/lib_itable/unsorted_table_list.h @@ -0,0 +1,83 @@ +/* #ifndef LIB_UNITABLE_H_ +#define LIB_UNITABLE_H_ + +#include +#include +#include +#include "../lib_list/list.h" +#include "../lib_pair/pair.h" +#include "../lib_itable/itable.h" +#include "../lib_vector/vector.h" + +template +class TUnsortedTable : public ITable{ + TList> _data; + +public: + + ~TUnsortedTable() = default; + TUnsortedTable() = default; + TUnsortedTable& operator=(const TUnsortedTable&) = delete; + + + void Insert(const TKey& key , const TVal& val) override; + void Remove(const TKey& key) override; + void Insert(const TKey& key) override; + TVal* Find(const TKey& key) override; + size_t Size() const override; + bool IsEmpty() const override; + TList>& Items() override { + return _data; + } +}; +template +void TUnsortedTable::Insert(const TKey& key) { + + for(auto& item : _data) { + if(item.first() == key) { // Исправлено: предполагается, что TPair имеет public first + return; + } + } + _data.push_back(TPair(key, TVal())); // Добавляем ключ с default-значением +}; + +template +void TUnsortedTable::Insert(const TKey& key, const TVal& val) { + for(auto& item : _data) { + if(item.first() == key) { + item.set_second() = val; // Обновляем значение, если ключ уже есть + return; + } + } + _data.push_back(TPair(key, val)); +}; +template +void TUnsortedTable::Remove(const TKey& key) { + for (auto it = _data.begin(); it != _data.end(); ) { + if (it->first() == key) { + it = _data.erase(it); // Исправлено: безопасное удаление + } else { + ++it; + } + } +}; + + +template +TVal* TUnsortedTable::Find(const TKey& key) { + for(auto& item : _data) { + if(item.first() == key) { + return &item.set_second(); + } + } + return nullptr; +}; + +template +size_t TUnsortedTable::Size() const { + return _data.size(); +}; +template +bool TUnsortedTable::IsEmpty() const { return _data.empty(); }; + +#endif //LIB_UNITABLE_H_ */ \ No newline at end of file diff --git a/lib_list/CMakeLists.txt b/lib_list/CMakeLists.txt new file mode 100644 index 0000000..148b539 --- /dev/null +++ b/lib_list/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(List) \ No newline at end of file diff --git a/lib_list/list.cpp b/lib_list/list.cpp new file mode 100644 index 0000000..7ad7c2a --- /dev/null +++ b/lib_list/list.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_list/list.h" diff --git a/lib_list/list.h b/lib_list/list.h new file mode 100644 index 0000000..0c7a1e1 --- /dev/null +++ b/lib_list/list.h @@ -0,0 +1,448 @@ +// Copyright 2024 Anvar +#pragma once +#include +#include +template +class TList; +template +class TNode +{ + + +public: + TNode *pnext; + TNode(); + TNode(T value, TNode *next); + TNode(const TNode &nod); + ~TNode(); + TNode &operator=(const TNode &nod); + void next(TNode *nod); + T value; + + + bool operator==(T value) const; + friend std::ostream &operator<<(std::ostream &os, const TNode &node); + + friend std::istream &operator>>(std::istream &is, TNode &node); + + friend class TList; + + +}; + +template +TNode::TNode() : value(), pnext(nullptr){} + +template +TNode::TNode(T value, TNode *next) : value(value), pnext(nullptr) {} + +template +TNode::TNode(const TNode &nod) : value(nod.value), pnext(nod.pnext) {} + +template +TNode::~TNode() +{ +} +template +void TNode::next(TNode *nod) { + pnext = nod; +} +template +TNode &TNode::operator=(const TNode &nod) +{ + if (this != &nod) + { + value = nod.value; + } + return *this; +} + +template +std::ostream &operator<<(std::ostream &os, const TNode &node) +{ + os << node.value; + return os; +} + +template +std::istream &operator>>(std::istream &is, TNode &node) +{ + is >> node.value; + return is; +} + +template +class TList { + +public: + TList(); + TList(const TList &list); + TList& operator=(const TList& other); + ~TList(); + void push_front(const T &value) noexcept; + void push_back(const T &value) noexcept; + void insert(TNode *node, const T &value); + void insert(size_t pos, const T &value); + void insertFront(const T &value); + void insertAfter(const T &value, const T &afterValue); + void insertAt(const T& value, size_t position); + TNode *find(const T &value) const noexcept; + bool isEmpty() const noexcept; + void pop_front(); + void pop_back(); + void removeValue(const T &value); + void removeAt(size_t position); + void erase(TNode *node); + void erase(size_t pos); + void replace(TNode *node, const T &value); + void replace(size_t pos, const T &value); +private: + class Iterator { + public: + Iterator(TNode* node = nullptr) : current(node) {} + + Iterator& operator++() { + if (current) { + current = current->pnext; + } + return *this; + } + + Iterator operator++(int) { + Iterator temp = *this; + ++(*this); + return temp; + } + + bool operator==(const Iterator& other) const { + return current == other.current; + } + + bool operator!=(const Iterator& other) const { + return current != other.current; + } + + T& operator*() { + return current->value; + } + + T* operator->() { + return ¤t->value; + } + + private: + TNode* current; + }; + public: + Iterator begin() { + return Iterator(head); + } + + Iterator end() { + return Iterator(nullptr); + } + +public: + TNode *head = nullptr; + TNode *tail = nullptr; + +}; + + +template +TList::TList() : head(nullptr), tail(nullptr) {} + +template +TList::TList(const TList &list) : head(nullptr), tail(nullptr) +{ + head = nullptr; + tail = nullptr; + TNode* current = list.head; + while (current) { + push_back(current->value); + current = current->pnext; + } +} +template +TList& TList::operator=(const TList& other) { + if (this != &other) { + while (head != nullptr) { + TNode* next = head->pnext; + delete head; + head = next; + } + tail = nullptr; + TNode* current = other.head; + while (current != nullptr) { + push_back(current->value); + current = current->pnext; + } + } + return *this; + +} +template +TList::~TList() { + while (head != nullptr) { + TNode* next = head->pnext; + delete head; + head = next; + } +} + +template +void TList::push_front(const T &value) noexcept +{ + TNode* newNode = new TNode(value, head); + head = newNode; + if (tail == nullptr) { + tail = newNode; + } +} +template +void TList::push_back(const T &value) noexcept +{ + TNode* newNode = new TNode(value, nullptr); + if (tail == nullptr) { + head = newNode; + tail = newNode; + } else { + tail->pnext = newNode; + tail = newNode; + } +} + +template +void TList::insert(TNode *node, const T &value) { + TNode* newNode = new TNode(value, nullptr); + newNode->next(node->pnext); + node->next(newNode); + if (newNode == tail) { + tail = newNode; + } +} + +template +void TList::insert(size_t pos, const T& value) { + if (pos == 0) { + push_front(value); + } else { + TNode* current = head; + size_t index = 0; + while (current && index < pos - 1) { + current = current->pnext; + index++; + } + if (current) { + TNode* newNode = new TNode(value, nullptr); + newNode->next(current->pnext); + current->next(newNode); + if (newNode == tail) { + tail = newNode; + } + } + } +} +template +void TList::insertAfter(const T &value, const T &afterValue) +{ + TNode *current = head; + while (current && current->value != afterValue) { + current = current->pnext; + } + if (current) { + TNode* newNode = new TNode(value, nullptr); + newNode->next(current->pnext); + current->next(newNode); + if (newNode == tail) { + tail = newNode; + } + } +} + +template +void TList::insertFront(const T &value) +{ + TNode *newNode = new TNode(value, head); + head = newNode; + if (tail == nullptr) + { + tail = newNode; + } +} + + +template +void TList::insertAt(const T& value, size_t position) { + if (position == 0) { + insertFront(value); + } else { + TNode* current = head; + size_t index = 0; + while (current && index < position - 1) { + current = current->pnext; + index++; + } + if (current) { + TNode* newNode = new TNode(value, nullptr); + newNode->next(current->pnext); + current->next(newNode); + if (newNode == tail) { + tail = newNode; + } + } + } +} + +template +TNode *TList::find(const T &value) const noexcept +{ + TNode *current = head; + while (current && current->value != value) + { + current = current->pnext; + } + return current; // returns null if value is not found +} +template +bool TList::isEmpty() const noexcept +{ + return head == nullptr && tail == nullptr; +} + +template +void TList::pop_front() +{ + + TNode* temp = head; + head = head->pnext; + delete temp; +} + +template +void TList::pop_back() +{ + if (head) { + if (head == tail) { // Если в списке только один элемент + delete head; + head = tail = nullptr; + } else { + TNode* current = head; + while (current->pnext != tail) { // Идем до предпоследнего элемента + current = current->pnext; + } + delete tail; + current->pnext = nullptr; + tail = current; // Обновляем указатель на tail + } + } +} + +template +void TList::removeValue(const T &value) +{ + if (head) { + TNode* current = head; + TNode* prev = nullptr; + while (current && current->value != value) { + prev = current; + current = current->pnext; + } + if (current) { + if (prev) { + prev->next(current->pnext); + } else { + head = current->pnext; + } + delete current; + if (head == nullptr) { + tail = nullptr; + } + } + } +} + +template +void TList::removeAt(size_t position) { + if (position == 0) { + pop_front(); + } else { + TNode* current = head; + TNode* prev = nullptr; + size_t index = 0; + while (current && index < position) { + prev = current; + current = current->pnext; + index++; + } + if (current) { + if (prev) { + prev->next(current->pnext); + } else { + head = current->pnext; + } + delete current; + if (head == nullptr) { + tail = nullptr; + } + } + } +} +template +void TList::erase(TNode *node) { + if (node == nullptr) { + throw std::invalid_argument("Node pointer is nullptr"); + } + TNode* current = head; + TNode* prev = nullptr; + while (current && current != node) { + prev = current; + current = current->pnext; + } + if (current) { + if (prev) { + prev->next(current->pnext); + } else { + head = current->pnext; + } + delete current; + if (head == nullptr) { + tail = nullptr; + } + } +} + +template +void TList::erase(size_t pos) { + if (pos == 0) { + erase(head); + return; + } + TNode *cur = head; + for (size_t i = 0; i < pos - 1; ++i) { + if (cur == nullptr) throw std::logic_error("Out of range"); + cur = cur->pnext; + } + erase(cur); +} +template +void TList::replace(TNode *node, const T &value) { + if (node == nullptr) { + throw std::invalid_argument("Node pointer is nullptr"); + } + node->value; +} +template +void TList::replace(size_t pos, const T &value) { + if (pos == 0) { + head->value = value; + return; + } + TNode *cur = head; + for (size_t i = 0; i < pos - 1; ++i) { + if (cur == nullptr) throw std::logic_error("Out of range"); + cur = cur->pnext; + } + if (cur->pnext == nullptr) throw std::logic_error("Out of range"); + cur->pnext->value = value; +} diff --git a/lib_matrix/CMakeLists.txt b/lib_matrix/CMakeLists.txt new file mode 100644 index 0000000..0f0c028 --- /dev/null +++ b/lib_matrix/CMakeLists.txt @@ -0,0 +1,2 @@ +create_project_lib(Matrix) + diff --git a/lib_matrix/matrix.cpp b/lib_matrix/matrix.cpp new file mode 100644 index 0000000..804de93 --- /dev/null +++ b/lib_matrix/matrix.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_matrix/matrix.h" diff --git a/lib_matrix/matrix.h b/lib_matrix/matrix.h new file mode 100644 index 0000000..c4e9387 --- /dev/null +++ b/lib_matrix/matrix.h @@ -0,0 +1,380 @@ +#include +#include +#include +#include +#include + +#define STEP_CAPACITY 15 + +enum State { empty, busy, deleted }; + +template class TDMassive; +template std::ostream& operator<<(std::ostream& out, const TDMassive& dmass); + +template +class TDMassive { + T* _data; + State* _states; + size_t _capacity; + size_t _size; + size_t _deleted; +public: + TDMassive() { + _size = 0; + _capacity = STEP_CAPACITY; + _data = new T[_capacity]; + _states = new State[_capacity]; + for (size_t i = 0; i < _capacity; i++) { + _states[i] = State::empty; + } + } + + TDMassive(const TDMassive& other) { + _size = other._size; + _capacity = other._capacity; + _data = new T[_capacity]; + _states = new State[_capacity]; + for (size_t i = 0; i < _capacity; i++) { + _data[i] = other._data[i]; + _states[i] = other._states[i]; + } + } + + TDMassive(const T* arr, size_t n) { + _capacity = n; + _data = new T[n]; + _states = new State[n]; + for (size_t i = 0; i < n; i++) { + _states[i] = State::busy; + _data[i] = arr[i]; + } + _size = n; + _deleted = 0; + } + + TDMassive(size_t n) { + _capacity = n; + _data = new T[n]; + _states = new State[n]; + for (size_t i = 0; i < n; i++) { + _states[i] = State::busy; + _data[i] = T(); + } + _size = n; + _deleted = 0; + } + + ~TDMassive() { delete[] _data; delete[] _states; } + + size_t size() const { return _size; } + + void swap(TDMassive& archive) { + std::swap(_data, archive._data); + std::swap(_states, archive._states); + std::swap(_capacity, archive._capacity); + std::swap(_size, archive._size); + std::swap(_deleted, archive._deleted); + } + + State getState(size_t index) const { + return _states[index]; + } + + size_t count_value(T value) const noexcept { + size_t count = 0; + for (size_t i = 0; i < _size; i++) { + if (_data[i] == value && _states[i] != State::deleted) { + count++; + } + } + return count; + } + + size_t getDeletedCount() const { + size_t count = 0; + for (size_t i = 0; i < _size; ++i) { + if (_states[i] == State::deleted) { + ++count; + } + } + return count; + } + + T& operator[](size_t index) { + if (index >= _size) { + throw std::out_of_range("Индекс выходит за пределы массива"); + } + for (size_t i = index; i < _size; i++){ + if(_states[i] == State::busy ){ + return _data[i]; + } + } + throw std::out_of_range("Элемент не найден"); + } + + const T& operator[](size_t index) const { + if (index >= _size) { + throw std::out_of_range("Индекс выходит за пределы массива"); + } + for (size_t i = index; i < _size; i++){ + if(_states[i] == State::busy ){ + return _data[i]; + } + } + throw std::out_of_range("Элемент не найден"); + } + + TDMassive& operator=(const TDMassive& other) { + if (this != &other) { + delete[] _data; + delete[] _states; + _size = other._size; + _capacity = other._capacity; + _deleted = other._deleted; + _data = new T[_capacity]; + _states = new State[_capacity]; + for (size_t i = 0; i < _size; i++) { + _data[i] = other._data[i]; + _states[i] = other._states[i]; + } + } + return *this; + } +}; + +template +std::ostream& operator<<(std::ostream& out, const TDMassive& dmass) { + for (size_t i = 0; i < dmass.size(); i++) { + out << dmass[i] << " "; + } + return out; +} + +template class TVector; +template std::ostream& operator<<(std::ostream& out, const TVector& vec); + +template +class TVector { +protected: + TDMassive _values; + size_t _start_index; +public: + TVector(size_t size = STEP_CAPACITY, size_t start_index = 0) : _values(size), _start_index(start_index) {} + TVector(const T* arr, size_t size, size_t start_index = 0) : _values(arr, size), _start_index(start_index) {} + TVector(const TVector &vec) : _values(vec._values), _start_index(vec._start_index) {} + ~TVector() {} + + T& operator[](size_t pos) { + if (pos - _start_index < 0 || pos - _start_index >= _values.size()) { throw std::logic_error("Uncorrect position in vector"); } + return _values[pos - _start_index]; + } + + const T& operator[](size_t pos) const { + if (pos - _start_index < 0 || pos - _start_index >= _values.size()) { throw std::logic_error("Uncorrect position in vector"); } + return _values[pos - _start_index]; + } + + TVector& operator=(const TVector& other) { + if (this != &other) { + _values = other._values; + _start_index = other._start_index; + } + return *this; + } + + TVector& operator+=(const TVector& other) { + if (_values.size() != other._values.size()) { throw std::logic_error("Vector must be with equal sizes"); } + for (size_t i = 0; i < _values.size(); i++) { + _values[i] += other._values[i]; + } + return *this; + } + + TVector operator+(const TVector& other) const { + TVector res(*this); + res += other; + return res; + } + + void swap(TVector& vec) { + _values.swap(vec._values); + std::swap(_start_index, vec._start_index); + } + + size_t size() const { return _values.size(); } + size_t start_index() const { return _start_index; } + + friend std::ostream& operator<<(std::ostream& out, const TVector& vec) { + for (size_t i = 0; i < vec.size(); i++) { + out << vec[i] << " "; + } + return out; + } + + TVector& operator*=(const T& scalar) { + for (size_t i = 0; i < this->size(); ++i) { + (*this)[i] *= scalar; + } + return *this; + } + + TVector& operator*=(const TVector& other) { + if (this->size() != other.size()) { + throw std::logic_error("Vectors must have the same size for addition."); + } + TVector result(this->size() * 2, this->_start_index); + for (size_t i = 0; i < this->size(); ++i) { + result.push_back((*this)[i]); + } + for (size_t i = 0; i < other.size(); ++i) { + result.push_back(other[i]); + } + *this = result; + return *this; + } +}; + +template class TUpperTriangularMatrix; +template std::ostream& operator<<(std::ostream& out, const TUpperTriangularMatrix& m); + +template +class TUpperTriangularMatrix : public TVector> { +private: + using TVector>::_values; + using TVector>::_start_index; +public: + TUpperTriangularMatrix(size_t size = STEP_CAPACITY) : TVector>(size) { + for (size_t i = 0; i < size; i++) { + _values[i] = TVector(size - i, i); + } + } + + TUpperTriangularMatrix(T const* const * arr, size_t size) : TVector>(size) { + for (size_t i = 0; i < size; i++) { + _values[i] = TVector(size - i, i); + for (size_t j = 0; j < size - i; j++) { + _values[i][j + i] = arr[i][j + i]; + } + } + } + + TUpperTriangularMatrix(const T* arr, size_t size) : TVector>(size) { + for (size_t i = 0; i < size; i++) { + _values[i] = TVector(size - i, i); + for (size_t j = 0; j < size - i; j++) { + _values[i][j + i] = arr[i * size + j + i]; + } + } + } + + TUpperTriangularMatrix(const TUpperTriangularMatrix &m) : TVector>(m) {} + TUpperTriangularMatrix(const TVector> &m) : TVector>(m) {} + ~TUpperTriangularMatrix() {} + + size_t size() const { return _values.size(); } + + using TVector>::operator[]; + using TVector>::operator=; + + TUpperTriangularMatrix& operator+=(const TUpperTriangularMatrix& other) { + if (this->size() != other.size()) { + throw std::logic_error("Matrices must be of the same size"); + } + for (size_t i = 0; i < this->size(); ++i) { + for (size_t j = i; j < this->size(); ++j) { + (*this)[i][j] += other[i][j]; + } + } + return *this; + } + + TUpperTriangularMatrix operator+(const TUpperTriangularMatrix& other) const { + TUpperTriangularMatrix result(*this); + result += other; + return result; + } + + TUpperTriangularMatrix operator*(const TUpperTriangularMatrix& other) { + if (size() != other.size()) { + throw std::invalid_argument("Matrices must be of the same size"); + } + TUpperTriangularMatrix result(size()); + for (size_t i = 0; i < size(); ++i) { + for (size_t j = i; j < size(); ++j) { + result[i][j] = 0; + for (size_t k = i; k <= j; ++k) { + result[i][j] += (*this)[i][k] * other[k][j]; + } + } + } + return result; + } + + TUpperTriangularMatrix operator*(const T& scalar) { + TUpperTriangularMatrix result(size()); + for (size_t i = 0; i < size(); ++i) { + for (size_t j = i; j < size(); ++j) { + result[i][j] = (*this)[i][j] * scalar; + } + } + return result; + } + + TUpperTriangularMatrix operator/(const T& scalar) { + if (scalar == 0) { + throw std::invalid_argument("Division by zero is not allowed."); + } + TUpperTriangularMatrix result(size()); + for (size_t i = 0; i < size(); ++i) { + for (size_t j = i; j < size(); ++j) { + result[i][j] = (*this)[i][j] / scalar; + } + } + return result; + } + + friend std::ostream& operator<<(std::ostream& out, const TUpperTriangularMatrix& m) { + for (size_t i = 0; i < m.size(); i++) { + for (size_t j = 0; j < m.size(); j++) { + if (j < i) { out << 0 << " "; } + else { out << m[i][j] << " "; } + } + out << "\n"; + } + return out; + } + TDMassive to_upper_triangular(const TDMassive& matrix, size_t size); +}; + +template +TDMassive to_upper_triangular(const TDMassive& matrix, size_t size) { + TDMassive result(matrix); + + for (size_t k = 0; k < size; ++k) { + if (result[k * size + k] == 0) { + bool swapped = false; + for (size_t i = k + 1; i < size; ++i) { + if (result[i * size + k] != 0) { + + for (size_t j = 0; j < size; ++j) { + std::swap(result[k * size + j], result[i * size + j]); + } + swapped = true; + break; + } + } + if (!swapped) { + throw std::runtime_error("Matrix cannot be converted to upper triangular due to zero pivot element"); + } + } + + for (size_t i = k + 1; i < size; ++i) { + T factor = result[i * size + k] / result[k * size + k]; + for (size_t j = k; j < size; ++j) { + result[i * size + j] -= factor * result[k * size + j]; + } + } + } + + return result; +} diff --git a/lib_merge_sorted_lists/CMakeLists.txt b/lib_merge_sorted_lists/CMakeLists.txt new file mode 100644 index 0000000..214e787 --- /dev/null +++ b/lib_merge_sorted_lists/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(MergeSortedLists) \ No newline at end of file diff --git a/lib_merge_sorted_lists/merge_sorted_lists.cpp b/lib_merge_sorted_lists/merge_sorted_lists.cpp new file mode 100644 index 0000000..c33f9f3 --- /dev/null +++ b/lib_merge_sorted_lists/merge_sorted_lists.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_merge_sorted_lists/merge_sorted_lists.h" diff --git a/lib_merge_sorted_lists/merge_sorted_lists.h b/lib_merge_sorted_lists/merge_sorted_lists.h new file mode 100644 index 0000000..fc9902c --- /dev/null +++ b/lib_merge_sorted_lists/merge_sorted_lists.h @@ -0,0 +1,32 @@ +#include +#include +#include +#include + +std::list mergeSortedLists(const std::list& list1, const std::list& list2) { + std::list mergedList; + auto it1 = list1.begin(); + auto it2 = list2.begin(); + + while (it1 != list1.end() && it2 != list2.end()) { + if (*it1 < *it2) { + mergedList.push_back(*it1); + ++it1; + } else { + mergedList.push_back(*it2); + ++it2; + } + } + + while (it1 != list1.end()) { + mergedList.push_back(*it1); + ++it1; + } + + while (it2 != list2.end()) { + mergedList.push_back(*it2); + ++it2; + } + + return mergedList; +} diff --git a/lib_pair/CMakeLists.txt b/lib_pair/CMakeLists.txt new file mode 100644 index 0000000..926e8ea --- /dev/null +++ b/lib_pair/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(Pair) \ No newline at end of file diff --git a/lib_pair/pair.cpp b/lib_pair/pair.cpp new file mode 100644 index 0000000..cf50ecb --- /dev/null +++ b/lib_pair/pair.cpp @@ -0,0 +1,3 @@ +// Copyright 2024 Anvar + +#include "../lib_pair/pair.h" diff --git a/lib_pair/pair.h b/lib_pair/pair.h new file mode 100644 index 0000000..fbd45af --- /dev/null +++ b/lib_pair/pair.h @@ -0,0 +1,66 @@ +#ifndef LIB_PAIR_PAIR_H_ +#define LIB_PAIR_PAIR_H_ + +#include +#include +#include + +template class TPair; + +template +class TPair { + T1 _first; + T2 _second; +public: + TPair() : _first(T1()), _second(T2()) { } + TPair(const T1& first, const T2& second) : _first(first), _second(second) { } + TPair(const TPair& pair) : _first(pair._first), _second(pair._second) { } + ~TPair() { } + + inline T1 first() const noexcept; + inline T2 second() const noexcept; + inline void set_first(const T1& value) noexcept; + inline void set_second(const T2& value) noexcept; + TPair& operator=(const TPair& pair) noexcept; + + void swap(TPair& pair) noexcept; +}; + +template +inline T1 TPair::first() const noexcept { + return _first; +} + +template +inline T2 TPair::second() const noexcept { + return _second; +} + +template +inline void TPair::set_first(const T1& value) noexcept { + _first = value; +} + +template +inline void TPair::set_second(const T2& value) noexcept { + _second = value; +} + +template +TPair& TPair::operator=(const TPair& pair) noexcept { + if (this != &pair) { + _first = pair._first; + _second = pair._second; + } + return *this; +} + + + +template +void TPair::swap(TPair& pair) noexcept { + std::swap(_first, pair._first); + std::swap(_second, pair._second); +} + +#endif // LIB_PAIR_PAIR_H_ \ No newline at end of file diff --git a/lib_polinom/CMakeLists.txt b/lib_polinom/CMakeLists.txt new file mode 100644 index 0000000..473f204 --- /dev/null +++ b/lib_polinom/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(Polinom) \ No newline at end of file diff --git a/lib_polinom/polinom.cpp b/lib_polinom/polinom.cpp new file mode 100644 index 0000000..e69de29 diff --git a/lib_polinom/polinom.h b/lib_polinom/polinom.h new file mode 100644 index 0000000..ca39aae --- /dev/null +++ b/lib_polinom/polinom.h @@ -0,0 +1,23 @@ +#pragma once +#include + + +template +class TPolinom { +public: + TPolinom(); + TPolinom(const TPolinom& polinom); + TPolinom(TPolinom&& polinom); + TPolinom& operator=(const TPolinom& polinom); + TPolinom& operator=(TPolinom&& polinom); + ~TPolinom(); + + void print() const noexcept; + +private: + T* _data; + size_t _size = 0; +}; + + + diff --git a/lib_queue/CMakeLists.txt b/lib_queue/CMakeLists.txt new file mode 100644 index 0000000..f0846b2 --- /dev/null +++ b/lib_queue/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(Queue) \ No newline at end of file diff --git a/lib_queue/queue.cpp b/lib_queue/queue.cpp new file mode 100644 index 0000000..216ea0c --- /dev/null +++ b/lib_queue/queue.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_queue/queue.h" diff --git a/lib_queue/queue.h b/lib_queue/queue.h new file mode 100644 index 0000000..b254aa0 --- /dev/null +++ b/lib_queue/queue.h @@ -0,0 +1,78 @@ +// Copyright 2024 Anvar + +#ifndef LIB_QUEUE_QUEUE_H_ +#define LIB_QUEUE_QUEUE_H_ + + +#include +#include + +#include "../lib_dmassive/archive.h" + +template +class TQueue { + + TDMassive _data; + public: + TQueue(); + TQueue(const TQueue& other); + TQueue& operator=(const TQueue& other); + ~TQueue(); + + void push_back(const T& value); + void pop_front(); + T front() const; + bool empty() const; + size_t size() const; + + void print() const; +}; + +template +TQueue::TQueue() : _data() {} + +template +TQueue::TQueue(const TQueue& other) : _data(other._data) {} + +template +TQueue& TQueue::operator=(const TQueue& other) { + if (this != &other) { + _data = other._data; + } + return *this; +} + +template +TQueue::~TQueue() { +} + +template +void TQueue::push_back(const T& value) { + _data.push_back(value); +} +template +void TQueue::pop_front() { + _data.pop_front(); +} +template +T TQueue::front() const { + if (empty()) { + throw std::logic_error( + "Queue is empty, cannot retrieve front element."); + } + return _data[0]; // Возвращаем первый элемент +} +template +bool TQueue::empty() const { + return _data.empty(); +} +template +size_t TQueue::size() const { + return _data.size(); +} + +template +void TQueue::print() const { + _data.print(); +} +#endif // LIB_QUEUE_QUEUE_H_ diff --git a/lib_stack/CMakeLists.txt b/lib_stack/CMakeLists.txt new file mode 100644 index 0000000..2a3a419 --- /dev/null +++ b/lib_stack/CMakeLists.txt @@ -0,0 +1,2 @@ +create_project_lib(Stack) +add_depend(Stack DMassive lib_dmassive) \ No newline at end of file diff --git a/lib_stack/stack.cpp b/lib_stack/stack.cpp new file mode 100644 index 0000000..092ca67 --- /dev/null +++ b/lib_stack/stack.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_stack/stack.h" diff --git a/lib_stack/stack.h b/lib_stack/stack.h new file mode 100644 index 0000000..2edf720 --- /dev/null +++ b/lib_stack/stack.h @@ -0,0 +1,76 @@ +#ifndef LIB_STACK_STACK_H_ +#define LIB_STACK_STACK_H_ + +#include +#include "../lib_dmassive/archive.h" + +template +class TStack { + TDMassive _data; + +public: + TStack(); + TStack(const TStack& other); + TStack& operator=(const TStack& other); + ~TStack(); + + void push(const T& value); + void pop(); + T top() const; + bool empty() const; + size_t size() const; + + void print() const; +}; + +template +TStack::TStack() : _data() {} + +template +TStack::TStack(const TStack& other) : _data(other._data) {} + +template +TStack& TStack::operator=(const TStack& other) { + if (this != &other) { + _data = other._data; + } + return *this; +} + +template +TStack::~TStack() {} + +template +void TStack::push(const T& value) { + _data.push_back(value); +} + +template +void TStack::pop() { + _data.pop_back(); +} + +template +T TStack::top() const { + if (empty()) { + throw std::underflow_error("Stack underflow"); + } + return _data[_data.size() - 1]; +} + +template +bool TStack::empty() const { + return _data.empty(); +} + +template +size_t TStack::size() const { + return _data.size(); +} + +template +void TStack::print() const { + _data.print(); +} + +#endif // LIB_STACK_STACK_H_ diff --git a/lib_stack_list/CMakeLists.txt b/lib_stack_list/CMakeLists.txt new file mode 100644 index 0000000..9ca1d0a --- /dev/null +++ b/lib_stack_list/CMakeLists.txt @@ -0,0 +1,2 @@ +create_project_lib(StackList) +add_depend(StackList List lib_list) \ No newline at end of file diff --git a/lib_stack_list/stack_list.cpp b/lib_stack_list/stack_list.cpp new file mode 100644 index 0000000..150936a --- /dev/null +++ b/lib_stack_list/stack_list.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_stack_list/stack_list.h" diff --git a/lib_stack_list/stack_list.h b/lib_stack_list/stack_list.h new file mode 100644 index 0000000..50620b0 --- /dev/null +++ b/lib_stack_list/stack_list.h @@ -0,0 +1,67 @@ + +#ifndef LIB_STACK_LIST_H_ +#define LIB_STACK_LIST_H_ + +#include +#include +#include "../lib_list/list.h" + +template +class TStack_LIST { +public: + TStack_LIST(); + ~TStack_LIST(); + + void push(const T& value); + void pop(); + T top() const; + bool isEmpty() const; + size_t size() const; + +private: + TList list; +}; + +template +TStack_LIST::TStack_LIST() {} + +template +TStack_LIST::~TStack_LIST() {} + +template +void TStack_LIST::push(const T& value) { + list.push_front(value); +} + +template +void TStack_LIST::pop() { + if (list.isEmpty()) { + throw std::underflow_error("Stack is empty"); + } + list.pop_front(); +} + +template +T TStack_LIST::top() const { + if (list.isEmpty()) { + throw std::underflow_error("Stack is empty"); + } + return list.head->value; +} + +template +bool TStack_LIST::isEmpty() const { + return list.isEmpty(); +} + +template +size_t TStack_LIST::size() const { + size_t count = 0; + TNode* current = list.head; + while (current != nullptr) { + ++count; + current = current->pnext; + } + return count; +} +#endif // LIB_STACK_LIST_H_ diff --git a/lib_tbsttable/CMakeLists.txt b/lib_tbsttable/CMakeLists.txt new file mode 100644 index 0000000..e110d15 --- /dev/null +++ b/lib_tbsttable/CMakeLists.txt @@ -0,0 +1,2 @@ +create_project_lib(TBSTable) +add_depend(TBSTable BinSearchTree lib_bin_search_tree) \ No newline at end of file diff --git a/lib_tbsttable/tbst_table.cpp b/lib_tbsttable/tbst_table.cpp new file mode 100644 index 0000000..fa4200b --- /dev/null +++ b/lib_tbsttable/tbst_table.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_tbsttable/tbst_table.h" diff --git a/lib_tbsttable/tbst_table.h b/lib_tbsttable/tbst_table.h new file mode 100644 index 0000000..5c724a4 --- /dev/null +++ b/lib_tbsttable/tbst_table.h @@ -0,0 +1,58 @@ +#ifndef LIB_TBST_TABLE_H_ +#define LIB_TBST_TABLE_H_ + +#include +#include +#include "../lib_list/list.h" +#include "../lib_pair/pair.h" +#include "../lib_bin_search_tree/bin_search_tree.h" +#include "../lib_itable/itable.h" + +template +class TBSTable : public ITable { + TBinSearchTree _data; + TList> _itemsList; // Для хранения элементов + +public: + // Обновляем список элементов при каждой модификации + void UpdateItems() { + _itemsList.Clear(); + _data.InOrderTraversal([this](const TKey& key, const TVal& val) { + _itemsList.PushBack(TPair(key, val)); + }); + } + + void Insert(const TKey& key) override { + _data.Insert(key, TVal()); + UpdateItems(); + } + + void Insert(const TKey& key, const TVal& val) override { + _data.Insert(key, val); + UpdateItems(); + } + + void Remove(const TKey& key) override { + _data.Remove(key); + UpdateItems(); + } + + TVal* Find(const TKey& key) override { + auto node = _data.Search(key); + return node ? &(node->value) : nullptr; + } + + size_t Size() const override { + return _data.Count(); + } + + bool IsEmpty() const override { + return _data.IsEmpty(); + } + + TList>& Items() override { + return _itemsList; + } +}; + +#endif // LIB_TBST_TABLE_H_ \ No newline at end of file diff --git a/lib_vector/CMakeLists.txt b/lib_vector/CMakeLists.txt new file mode 100644 index 0000000..d35a27e --- /dev/null +++ b/lib_vector/CMakeLists.txt @@ -0,0 +1,2 @@ +create_project_lib(Vector) +add_depend(Vector DMassive lib_dmassive) \ No newline at end of file diff --git a/lib_vector/vector.cpp b/lib_vector/vector.cpp new file mode 100644 index 0000000..f71a8ea --- /dev/null +++ b/lib_vector/vector.cpp @@ -0,0 +1,2 @@ +// Copyright 2024 Anvar +#include "../lib_vector/vector.h" diff --git a/lib_vector/vector.h b/lib_vector/vector.h new file mode 100644 index 0000000..78a4e5d --- /dev/null +++ b/lib_vector/vector.h @@ -0,0 +1,453 @@ +#pragma once +#include +#include +#include +#include "../lib_dmassive/archive.h" + +template class TVector; +template +TVector operator*(const TVector& vec, T scalar); +template +TVector operator*(T scalar, const TVector& vec); + +template +class TVector { + TDMassive _data; + size_t _start_index; + +public: + TVector(); + TVector(const TVector& vec); + explicit TVector(size_t n, size_t start_index = 0); + ~TVector(); + + void print() const noexcept; + + inline bool empty() const noexcept; + inline bool full() const noexcept; + + size_t size() const noexcept; + size_t start_index() const noexcept; + const T* data() const; + + void swap(TVector& vec); + + TVector& assign(const TVector& vec); + + void clear(); + void resize(size_t n, T value = T()); + + void push_back(T value); + void pop_back(); + + TVector& insert(const T* arr, size_t n, size_t pos); + TVector& insert(T value, size_t pos); + + TVector& replace(size_t pos, T new_value); + void push_front(T value); + void pop_front(); + + TVector& erase(size_t pos, size_t n); + TVector& remove_all(T value); + TVector& remove_first(T value); + TVector& remove_last(T value); + TVector& remove_by_index(size_t pos); + + size_t* find_all(T value) const noexcept; + size_t find_first(T value) const; + size_t find_last(T value) const; + + T& operator[](size_t index); + const T& operator[](size_t index) const; + + TVector& operator=(const TVector& vec) noexcept; + TVector operator+(const TVector& vec) const; + TVector operator-(const TVector& vec) const; + friend TVector operator*(const TVector& vec, T scalar); + friend TVector operator*(T scalar, const TVector& vec); + TVector& operator+=(const TVector& vec); + TVector& operator-=(const TVector& vec); + TVector& operator*=(const TVector& other); + TVector& operator*=(const T& scalar); + bool operator==(const TVector& vec) const; + bool operator!=(const TVector& vec) const; + + class Iterator { + public: + Iterator(TVector* vec, size_t index) : _vec(vec), _index(index) {} + + Iterator& operator++() { + ++_index; + return *this; + } + + Iterator operator++(int) { + Iterator temp = *this; + ++_index; + return temp; + } + + bool operator==(const Iterator& other) const { + return _index == other._index; + } + + bool operator!=(const Iterator& other) const { + return _index != other._index; + } + + T& operator*() { + return (*_vec)[_index]; + } + + T* operator->() { + return &(*_vec)[_index]; + } + + private: + TVector* _vec; + size_t _index; + }; + + Iterator begin() { + return Iterator(this, _start_index); + } + + Iterator end() { + return Iterator(this, _start_index + _data.size()); + } +}; + +template +TVector::TVector() : _start_index(0) {} + +template +TVector::TVector(const TVector& vec) : + _data(vec._data), _start_index(vec._start_index) {} + +template +TVector::TVector(size_t n, size_t start_index) : + _data(n - start_index), _start_index(start_index) {} + +template +TVector::~TVector() {} + +template +void TVector::print() const noexcept { + for (size_t i = _start_index; i < _data.size(); ++i) { + std::cout << _data[i] << " "; + } + std::cout << std::endl; +} + +template +inline bool TVector::empty() const noexcept { + return _data.empty(); +} + +template +inline bool TVector::full() const noexcept { + return _data.full(); +} + +template +size_t TVector::size() const noexcept { + return _data.size(); +} + +template +size_t TVector::start_index() const noexcept { + return _start_index; +} + +template +const T* TVector::data() const { + return _data.data(); +} + +template +void TVector::swap(TVector& vec) { + _data.swap(vec._data); + std::swap(_start_index, vec._start_index); +} + +template +TVector& TVector::assign(const TVector& vec) { + _data.assign(vec._data); + _start_index = vec._start_index; + return *this; +} + +template +void TVector::clear() { + _data.clear(); + _start_index = 0; +} + +template +void TVector::resize(size_t n, T value) { + if (n > _data.capacity()) { + throw std::out_of_range("out of range. capacity < size"); + } + _data.resize(n, value); +} + +template +void TVector::push_back(T value) { + if ((_data.size() + 1) > _data.capacity()) { + throw std::out_of_range("out of range. capacity < size"); + } + _data.push_back(value); +} + +template +void TVector::pop_back() { + if (_data.empty()) { + throw std::out_of_range("pop_back() called on empty vector"); + } + _data.pop_back(); +} + +template +void TVector::push_front(T value) { + if ((_data.size() + 1) > _data.capacity()) { + throw std::out_of_range("out of range. capacity < size"); + } + _data.push_front(value); +} + +template +void TVector::pop_front() { + if (_data.empty()) { + throw std::out_of_range("pop_front() called on empty vector"); + } + _data.pop_front(); +} + +template +TVector& TVector::insert(const T* arr, size_t n, size_t pos) { + if (pos > _data.size()) { + throw std::out_of_range("out of range. pos > size"); + } + if ((_data.size() + n) > _data.capacity()) { + throw std::out_of_range("out of range. capacity < size"); + } + _data.insert(arr, n, pos); + return *this; +} + +template +TVector& TVector::insert(T value, size_t pos) { + if (pos > _data.size()) { + throw std::out_of_range("out of range. pos > size"); + } + if ((_data.size() + 1) > _data.capacity()) { + throw std::out_of_range("out of range. capacity < size"); + } + _data.insert(value, pos); + return *this; +} + +template +TVector& TVector::replace(size_t pos, T new_value) { + if (pos >= _data.size()) { + throw std::out_of_range("out of range. pos >= size"); + } + _data.replace(pos, new_value); + return *this; +} + +template +TVector& TVector::erase(size_t pos, size_t n) { + if (pos >= _data.size()) { + throw std::out_of_range("out of range. pos >= size"); + } + if ((pos + n) > _data.size()) { + throw std::out_of_range("out of range. pos + n > size"); + } + _data.erase(pos, n); + return *this; +} + +template +TVector& TVector::remove_all(T value) { + _data.remove_all(value); + return *this; +} + +template +TVector& TVector::remove_first(T value) { + _data.remove_first(value); + return *this; +} + +template +TVector& TVector::remove_last(T value) { + _data.remove_last(value); + return *this; +} + +template +TVector& TVector::remove_by_index(size_t pos) { + if (pos >= _data.size()) { + throw std::out_of_range("out of range. pos >= size"); + } + _data.remove_by_index(pos); + return *this; +} + +template +size_t* TVector::find_all(T value) const noexcept { + return _data.find_all(value); +} + +template +size_t TVector::find_first(T value) const { + return _data.find_first(value); +} + +template +size_t TVector::find_last(T value) const { + return _data.find_last(value); +} + +template +T& TVector::operator[](size_t index) { + if (index >= _data.size()) { + throw std::out_of_range("out of range. index >= size"); + } + return _data[index - _start_index]; +} + +template +const T& TVector::operator[](size_t index) const { + if (index >= _data.size()) { + throw std::out_of_range("out of range. index >= size"); + } + return _data[index - _start_index]; +} + +template +TVector& TVector::operator=(const TVector& vec) noexcept { + if (this != &vec) { + _data = vec._data; + _start_index = vec._start_index; + } + return *this; +} + +template +TVector TVector::operator+(const TVector& vec) const { + if (this->size() != vec.size()) { + throw std::logic_error("Vectors must have the same size for addition."); + } + TVector result(this->size(), this->_start_index); + for (size_t i = 0; i < this->size(); ++i) { + result.push_back((*this)[i] + vec[i]); + } + return result; +} + +template +TVector TVector::operator-(const TVector& vec) const { + if (this->size() != vec.size()) { + throw std::logic_error("Vectors must have the same size for subtraction."); + } + TVector result(this->size(), this->_start_index); + for (size_t i = 0; i < this->size(); ++i) { + result.push_back((*this)[i] - vec[i]); + } + return result; +} + +template +TVector& TVector::operator+=(const TVector& vec) { + size_t pos = 0; + size_t pos2 = 0; + for (size_t i = 0; i < size(); i++) { + if (_start_index + i < vec._start_index) { + pos++; + pos2++; + continue; + } + if (_start_index <= vec._start_index + i) { + replace(pos - 1, _data[pos++] + vec._data[i - pos2]); + } + } + return *this; +} + +template +TVector& TVector::operator-=(const TVector& vec) { + if (this->size() != vec.size()) { + throw std::logic_error("Vectors must have the same size for subtraction."); + } + for (size_t i = 0; i < this->size(); ++i) { + (*this)[i] -= vec[i]; + } + return *this; +} + +template +TVector& TVector::operator*=(const T& scalar) { + for (size_t i = 0; i < this->size(); ++i) { + (*this)[i] *= scalar; + } + return *this; +} +template +TVector& TVector::operator*=(const TVector& other) { + if (this->size() != other.size()) { + throw std::logic_error("Vectors must have the same size for addition."); + } + TVector result(this->size() * 2, this->_start_index); + for (size_t i = 0; i < this->size(); ++i) { + result.push_back((*this)[i]); + } + for (size_t i = 0; i < other.size(); ++i) { + result.push_back(other[i]); + } + *this = result; + return *this; +} + + + +template +bool TVector::operator==(const TVector& vec) const { + if ((_start_index != vec._start_index) || (size() != vec.size())) { + return false; + } + for (size_t i = 0; i < size(); i++) { + if (_data[i] != vec._data[i]) { + return false; + } + } + return true; +} + +template +bool TVector::operator!=(const TVector& vec) const { + if ((_start_index != vec._start_index) || (size() != vec.size())) { + return true; + } + for (size_t i = 0; i < size(); i++) { + if (_data[i] != vec._data[i]) { + return true; + } + } + return false; +} + +template +TVector operator*(const TVector& vec, T scalar) { + TVector result(vec._data.capacity(), vec._start_index); + for (size_t i = 0; i < vec.size(); i++) { + result.push_back(vec[i] * scalar); + } + return result; +} + +template +TVector operator*(T scalar, const TVector& vec) { + return vec * scalar; +} diff --git a/main/main.cpp b/main/main.cpp index 217f897..7e06a3d 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1,37 +1,496 @@ // Copyright 2024 Marina Usova +#include +#include +#include +#include +#include +#include +#include +#define HEAP -#define EASY_EXAMPLE #ifdef EASY_EXAMPLE +#include #include -#include + #include "../lib_easy_example/easy_example.h" int main() { - int a, b; - float result; + int a, b; + float result; - a = 1; b = 4; + a = 1; b = 4; - try { - result = division(a, b); - std::cout << a << " / " << b << " = " - << std::setprecision(2) << result << std::endl; - } catch (std::exception err) { - std::cerr << err.what() << std::endl; - } + try { + result = division(a, b); + std::cout << a << " / " << b << " = " + << std::setprecision(2) << result << std::endl; + } + catch (std::exception& err) { + std::cerr << err.what() << std::endl; + } + + a = 1; b = 0; + + try { + result = division(a, b); + std::cout << a << " / " << b << " = " + << std::setprecision(2) << result << std::endl; + } + catch (std::exception& err) { + std::cerr << err.what() << std::endl; + } + return 0; +} +#endif // EASY_EXAMPLE - a = 1; b = 0; +#ifdef PAIR +#include "../lib_pair/pair.h" - try { - result = division(a, b); - std::cout << a << " / " << b << " = " - << std::setprecision(2) << result << std::endl; - } catch (std::exception err) { - std::cerr << err.what() << std::endl; - } +int main() { + TPair pair1(1, 4); + TPair pair2; - return 0; + pair1.swap(pair2); + return 0; } +#endif // PAIR -#endif // EASY_EXAMPLE +#ifdef TLIST +#include +#include +#include "../lib_list/list.h" + +int main() { + TList list; + + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.push_back(4); + + // Использование итератора для чтения + std::cout << "Reading elements using iterator:" << std::endl; + for (auto it = list.begin(); it != list.end(); ++it) { + std::cout << *it << " "; + } + std::cout << std::endl; + + // Использование итератора для записи + std::cout << "Writing elements using iterator:" << std::endl; + int newValue = 10; + for (auto it = list.begin(); it != list.end(); ++it) { + *it += newValue; + newValue += 10; + } + + // Использование итератора для чтения после записи + std::cout << "Reading elements after writing using iterator:" << std::endl; + for (auto it = list.begin(); it != list.end(); ++it) { + std::cout << *it << " "; + } + std::cout << std::endl; + + return 0; +} +#endif // TLIST + + +#ifdef STACK +#include "../lib_stack/stack.h" // включаем ваш файл заголовка + +int main() { + + + constexpr size_t N = 1000; // Количество элементов для тестирования + TStack stack; + + // Измерение времени для push + auto start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + stack.push(i); + } + auto end = std::chrono::high_resolution_clock::now(); + std::cout << "push time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + // Измерение времени для top + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + volatile int value = stack.top(); // Используем volatile, чтобы избежать оптимизации + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "top time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + // Измерение времени для pop + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + stack.pop(); + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "pop time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + return 0; +} +#endif // STACK + +#ifdef DMASSIVE +#include "../lib_dmassive/archive.h" + +int main() { + constexpr size_t N = 1000; + TDMassive massive; + + // Измерение времени для push_back + auto start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + massive.push_back(i); + } + auto end = std::chrono::high_resolution_clock::now(); + std::cout << "push_back time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + // Измерение времени для push_front + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + massive.push_front(i); + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "push_front time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + + // Измерение времени для pop_front + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + massive.pop_front(); + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "pop_front time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + // Измерение времени для push_front + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + massive.pop_back(); + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "pop_back time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + // Измерение времени для insert + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + massive.insert(i, massive.size() / 2); // Вставка в середину + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "insert time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + // Измерение времени для find + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + massive.find_first(i); + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "find_first time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + return 0; +} +#endif // DMASSIVE + +#ifdef TDLIST +#include "../lib_list/list.h" +int main() { + constexpr size_t N = 100000; // Количество элементов для тестирования + TList list; + +// Измерение времени для push_back + auto start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + list.push_back(i); + } + auto end = std::chrono::high_resolution_clock::now(); + std::cout << "push_back time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + // Измерение времени для push_front + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + list.push_front(i); + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "push_front time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + +// Измерение времени для pop_back + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + list.pop_front(); + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "pop_back time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + + + + + + /* // Измерение времени для insert + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + list.insertAt(N / 2, i); // Вставка в середину + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "insert time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + // Измерение времени для find + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + list.find(i); + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "find time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; */ + + return 0; +} +#endif // TDLIST + +#ifdef STACK_LIST +#include "../lib_stack_list/stack_list.h" + +int main() { + constexpr size_t N = 1000000; + TStack_LIST stack; + + // Измерение времени для push + auto start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + stack.push(i); + } + auto end = std::chrono::high_resolution_clock::now(); + std::cout << "push time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + // Проверка количества элементов в стеке + std::cout << "Stack size after push: " << stack.size() << std::endl; + + // Измерение времени для pop + start = std::chrono::high_resolution_clock::now(); + for (int i = 0; i < N; ++i) { + if (!stack.isEmpty()) { + stack.pop(); + } else { + std::cerr << "Stack is empty, cannot pop!" << std::endl; + break; + } + } + end = std::chrono::high_resolution_clock::now(); + std::cout << "pop time: " + << std::chrono::duration_cast(end - start).count() + << " ms" << std::endl; + + // Проверка количества элементов после pop + std::cout << "Stack size after pop: " << stack.size() << std::endl; + + return 0; +} +#endif + +#ifdef MATRIX +#include "../lib_matrix/matrix.h" + + + +int main() { + int vec_data[] = { 1, 2, 3, 4, 5 }; + int vec_size = 5; + TVector vec1(vec_data, vec_size), vec2(5), vec3(10), res_v(5); + + for (int i = 0; i < 5; i++) { + vec2[i] = -5 + rand() % 11; + } + + int matrix_size = 3; + int **matrix_data = new int*[matrix_size]; + for (int i = 0; i < matrix_size; i++) { + matrix_data[i] = new int[matrix_size]; + for (int j = 0; j < matrix_size; j++) { + matrix_data[i][j] = -5 + rand() % 11; + } + } + + TUpperTriangularMatrix m1(matrix_data, matrix_size); + + for (int i = 0; i < matrix_size; i++) { + matrix_data[i] = new int[matrix_size]; + for (int j = 0; j < matrix_size; j++) { + matrix_data[i][j] = -5 + rand() % 11; + } + } + + TUpperTriangularMatrix m2(matrix_data, matrix_size), res_m; + + std::cout << "CHECK VECTOR OPERATIONs" << std::endl << std::endl; + + std::cout << "vec1: " << vec1 << std::endl; + std::cout << "vec2: " << vec2 << std::endl; + + vec1 += vec2; + + std::cout << "vec1+=vec2" << std::endl; + std::cout << "vec1: " << vec1 << std::endl; + std::cout << "vec2: " << vec2 << std::endl; + + res_v = vec1 + vec2; + + std::cout << "res = vec1 + vec2" << std::endl; + std::cout << "res: " << res_v << std::endl; + std::cout << "vec1: " << vec1 << std::endl; + std::cout << "vec2: " << vec2 << std::endl; + + std::cout << std::endl << "CHECK MATRIX OPERATIONs" << std::endl << std::endl; + + std::cout << "m1: " << std::endl << m1 << std::endl; + std::cout << "m2: " << std::endl << m2 << std::endl; + + m1 += m2; + + std::cout << "m1+=m2" << std::endl; + std::cout << "m1: " << m1 << std::endl; + std::cout << "m2: " << m2 << std::endl; + + res_m = m1 + m2; + + std::cout << "res = m1 + m2" << std::endl; + std::cout << "res: " << std::endl<< res_m << std::endl; + std::cout << "m1: " << std::endl << m1 << std::endl; + std::cout << "m2: " << std::endl << m2 << std::endl; + + + + TDMassive matrix(matrix_size * matrix_size); + + + for (int i = 0; i < matrix_size; i++) { + for (int j = 0; j < matrix_size; j++) { + if (i == j) { + matrix[i * matrix_size + j] = -5 + rand() % 10 + 1; // Ненулевая диагональ + } else { + matrix[i * matrix_size + j] = -5 + rand() % 11; + } + } + } + + std::cout << "Original Matrix:" << std::endl; + for (int i = 0; i < matrix_size; i++) { + for (int j = 0; j < matrix_size; j++) { + std::cout << matrix[i * matrix_size + j] << " "; + } + std::cout << std::endl; + } + + try { + TDMassive triangular_matrix = to_upper_triangular(matrix, matrix_size); + + std::cout << "\nUpper Triangular Matrix:" << std::endl; + for (int i = 0; i < matrix_size; i++) { + for (int j = 0; j < matrix_size; j++) { + std::cout << triangular_matrix[i * matrix_size + j] << " "; + } + std::cout << std::endl; + } + } catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + + system("pause"); + return 0; + +} +#endif + +#ifdef ITERATOR +#include "../lib_vector/vector.h" +int main() { + TVector vec(10); + for (int i = 0; i < 10; i++) { + vec.push_back(i); + } + for (auto it = vec.begin(); it != vec.end(); ++it) { + std::cout << *it << " "; + } + std::cout << std::endl; + return 0; +} +#endif +#ifdef HEAP +#include "../lib_heap/heap.h" +#include "../lib_vector/vector.h" +template +void sortMassivchettam(TVector& arr, int k ){ + Heap minHeap(10); + + for (int i = 0; i <= k && i < arr.size(); ++i) { + minHeap.push_heap(arr[i]); + } + + int index = 0; + + for (int i = k + 1; i < arr.size(); ++i) { + + arr[index++] = minHeap.top(); + minHeap.pop_heap(); + + minHeap.push_heap(arr[i]); + } + + while (!minHeap.is_empty()) { + arr[index++] = minHeap.top(); + minHeap.pop_heap(); + } +} +int main() { + TVector arr; + arr.push_back(6); + arr.push_back(5); + arr.push_back(3); + arr.push_back(2); + arr.push_back(8); + arr.push_back(10); + arr.push_back(9); + + int k = 3; + + sortMassivchettam(arr, k); + + + for (size_t i = 0; i < arr.size(); ++i) { + std::cout << arr[i] << " "; + } + // Вывод: 2 3 5 6 8 9 10 + + return 0; +} +#endif \ No newline at end of file diff --git a/main/utilites.h b/main/utilites.h new file mode 100644 index 0000000..ce5e007 --- /dev/null +++ b/main/utilites.h @@ -0,0 +1,216 @@ +#pragma once +#include +#include +#include "../lib_dmassive/archive.h" + +namespace InputSystem { +enum InsertMode {Back, Front, OneValue, SeveralValues}; +enum RemoveMode{Back1, Front1, All, First, Last, OneValue1, SeveralValues1}; +enum FindMode{FAll, FFirst, FLast}; + +template +T* remove(const size_t& n, const size_t& pos, +const InputSystem::RemoveMode& mode) noexcept { + T* value = nullptr; + mode = Back1; + int user; + std::cout << "Choose remove mode:\n"; + std::cout << "1 - back,\n"; + std::cout << "2 - front,\n"; + std::cout << "3 - by value,\n"; + std::cout << "4 - at given position.\n"; + std::cout << "Your choose: "; + std::cin >> user; + if (user == 1) { + mode = Back1; + } + if (user == 2) mode = Front1; + if (user == 3) { + std::cout << "Remove by value:\n"; + std::cout << "1 - first coincidence,\n"; + std::cout << "2 - last coincidence,\n"; + std::cout << "3 - all coincidence.\n"; + std::cout << "Your choose: "; + std::cin >> user; + if (user == 1) mode = First; + if (user == 2) mode = Last; + if (user == 3) mode = All; + } + if (user == 4) { + std::cout << "How many values need to be removed:\n"; + std::cout << "1 - one value,\n"; + std::cout << "2 - several values.\n"; + std::cout << "Your choose: "; + std::cin >> user; + if (user == 1) mode = OneValue1; + if (user == 2) mode = SeveralValues1; + } + if (mode == First || mode == Last || mode == All) { + n = 1; + value = new T[n]; + std::cout << "Input value for remove: "; + std::cin >> value[0]; + } + if (mode == SeveralValues1) { + std::cout << "Input number of values for remove: "; + std::cin >> n; + } + if (mode == OneValue1 || mode == SeveralValues1) { + std::cout << "Input position for remove: "; + std::cin >> pos; + } + return value; +} + +template +T* insert(const size_t& n, const size_t& pos, +const InputSystem::InsertMode& mode) noexcept { + T* value = nullptr; + mode = Back; + int user; + std::cout << "Choose insert mode:\n"; + std::cout << "1 - to the back,\n"; + std::cout << "2 - to the front,\n"; + std::cout << "3 - at given position.\n"; + std::cout << "Your choose: "; + std::cin >> user; + if (user == 1) mode = Back; + if (user == 2) mode = Front; + if (user == 3) { + std::cout << "How many values need to insert:\n"; + std::cout << "1 - one value,\n"; + std::cout << "2 - several values.\n"; + std::cout << "Your choose: "; + std::cin >> user; + if (user == 1) mode = OneValue; + if (user == 2) mode = SeveralValues; + } + if (mode == Back || mode == Front || mode == OneValue) { + n = 1; + value = new T[n]; + std::cout << "Input value for insert: "; + std::cin >> value[0]; + } + if (mode == SeveralValues) { + std::cout << "Input number of values for insert: "; + std::cin >> n; + value = new T[n]; + std::cout << "Input values for insert (between space): "; + for (size_t i = 0; i < n; i++) { + std::cin >> value[i]; + } + } + if (mode == OneValue || mode == SeveralValues) { + std::cout << "Input position for insert: "; + std::cin >> pos; + } + return value; +} + +template +T* find(const InputSystem::FindMode& mode) noexcept { + T* value = nullptr; + mode = FFirst; + int user; + std::cout << "Choose find mode:\n"; + std::cout << "1 - find all,\n"; + std::cout << "2 - find first,\n"; + std::cout << "3 - find last.\n"; + std::cout << "Your choose: "; + std::cin >> user; + if (user == 1) mode = FAll; + if (user == 2) mode = FFirst; + if (user == 3) mode = FLast; + if (mode == FFirst || mode == FLast) { + value = new T; + std::cout << "Input value for find: "; + std::cin >> value[0]; + } + if (mode == FAll) { + value = new T[5]; + std::cout << "Input values for find(max 5) ('.' for exit): "; + for (size_t i = 0; i < 5; i++) { + std::cin >> value[i]; + if (value[i] == '.') { + break; + } + } + } + return value; +} +} // namespace InputSystem + +namespace OutputSystem { + +static void setCursor(int column, int line) { + COORD coord; + coord.X = column; + coord.Y = line; + SetConsoleCursorPosition( + GetStdHandle(STD_OUTPUT_HANDLE), + coord); +} + +static void getCursor(int* column, int* line) noexcept { + CONSOLE_SCREEN_BUFFER_INFO csbi; + + if (GetConsoleScreenBufferInfo + (GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) { + if (column != nullptr) { + *column = csbi.dwCursorPosition.X; + } + if (line != nullptr) { + *line = csbi.dwCursorPosition.Y; + } + } else { + if (column != nullptr) { + *column = 0; + } + if (line != nullptr) { + *line = 0; + } + } +} + +static void insert() noexcept { + std::cout << "Done." << std::endl; +} +static void remove() noexcept { + std::cout << "Done." << std::endl; +} + +template +static void find(size_t* values, +const InputSystem::FindMode mode, +const TDMassive& archive, +size_t count) noexcept { + system("cls"); + const auto& data = archive.data(); + std::cout << "Matches found: "; + for (size_t i = 0; i < count; i++) { + std::cout << values[i] << " "; + } + std::cout << std::endl; + archive.print(); + std::cout << std::endl; + for (int i = 0; i < count; i++) { + std::cout << data[values[i]]; + if (i < count - 1) { + std::cout << ", "; + } + } +} + +template +void show(const TDMassive& archive) noexcept { + std::cout << "Archive: { "; + archive.print(); + if (!archive.empty()) { + int column, line; + getCursor(column, line); + column -= 2; + setCursor(column, line); + } + std::cout << " }\n"; +} +} // namespace OutputSystem \ No newline at end of file diff --git a/tests/test_avl.cpp b/tests/test_avl.cpp new file mode 100644 index 0000000..f51675b --- /dev/null +++ b/tests/test_avl.cpp @@ -0,0 +1,72 @@ +// Copyright 2024 Anvar + +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#define FRIEND_TEST_CASES +#include "../gtest/gtest.h" +#include "../lib_avl/avl.h" + + + +TEST(AVLTreeTest, LeftLeftRotation) { + AVLTree tree; + tree.insert(30); + tree.insert(20); + tree.insert(10); // Должен вызвать правый поворот + + auto root = tree.getRoot(); + EXPECT_EQ(root->key, 20); + EXPECT_EQ(root->left->key, 10); + EXPECT_EQ(root->right->key, 30); +} + +TEST(AVLTreeTest, RightRightRotation) { + AVLTree tree; + tree.insert(10); + tree.insert(20); + tree.insert(30); // Должен вызвать левый поворот + + auto root = tree.getRoot(); + EXPECT_EQ(root->key, 20); + EXPECT_EQ(root->left->key, 10); + EXPECT_EQ(root->right->key, 30); +} + +TEST(AVLTreeTest, LeftRightRotation) { + AVLTree tree; + tree.insert(30); + tree.insert(10); + tree.insert(20); // Должен вызвать лево-правый поворот + + auto root = tree.getRoot(); + EXPECT_EQ(root->key, 20); + EXPECT_EQ(root->left->key, 10); + EXPECT_EQ(root->right->key, 30); +} + +TEST(AVLTreeTest, RightLeftRotation) { + AVLTree tree; + tree.insert(10); + tree.insert(30); + tree.insert(20); // Должен вызвать право-левый поворот + + auto root = tree.getRoot(); + EXPECT_EQ(root->key, 20); + EXPECT_EQ(root->left->key, 10); + EXPECT_EQ(root->right->key, 30); +} + +TEST(AVLTreeTest, ComplexOperations) { + AVLTree tree; + // Вставка целых чисел от 0 до 99 + for (int i = 0; i < 100; ++i) { + tree.insert(i); + } + // Удаление четных чисел + for (int i = 0; i < 100; i += 2) { + tree.remove(i); + } + // Проверка, остались ли нечетные числа + for (int i = 1; i < 100; i += 2) { + EXPECT_TRUE(tree.search(i)); + } +} \ No newline at end of file diff --git a/tests/test_bin_search_tree.cpp b/tests/test_bin_search_tree.cpp new file mode 100644 index 0000000..87bc5ce --- /dev/null +++ b/tests/test_bin_search_tree.cpp @@ -0,0 +1,150 @@ +// Copyright 2024 Anvar +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#define FRIEND_TEST_CASES +#include "../gtest/gtest.h" +#include "../lib_bin_search_tree/bin_search_tree.h" + +TEST(TBinSearchTreeTest, InsertAndSearch) { + TBinSearchTree tree; + + // Check empty tree + int key = 10; + EXPECT_EQ(tree.search(key), nullptr); + + // Insert elements + tree.insert(10, 10); + tree.insert(5, 5); + tree.insert(15, 15); + tree.insert(3, 3); + tree.insert(7, 7); + tree.insert(12, 12); + tree.insert(20, 20); + + // Check elements through search() + key = 10; EXPECT_NE(tree.search(key), nullptr); + key = 5; EXPECT_NE(tree.search(key), nullptr); + key = 15; EXPECT_NE(tree.search(key), nullptr); + key = 3; EXPECT_NE(tree.search(key), nullptr); + key = 7; EXPECT_NE(tree.search(key), nullptr); + key = 12; EXPECT_NE(tree.search(key), nullptr); + key = 20; EXPECT_NE(tree.search(key), nullptr); + key = 99; EXPECT_EQ(tree.search(key), nullptr); // Non-existent element +} + +TEST(TBinSearchTreeTest, RemoveLeaf) { + TBinSearchTree tree; + tree.insert(10, 10); + tree.insert(5, 5); + tree.insert(15, 15); + + int key = 5; + tree.remove(key); + EXPECT_EQ(tree.search(key), nullptr); + key = 10; EXPECT_NE(tree.search(key), nullptr); + key = 15; EXPECT_NE(tree.search(key), nullptr); +} + +TEST(TBinSearchTreeTest, RemoveNodeWithOneChild) { + TBinSearchTree tree; + tree.insert(10, 10); + tree.insert(5, 5); + tree.insert(3, 3); + + int key = 5; + tree.remove(key); + EXPECT_EQ(tree.search(key), nullptr); + key = 3; EXPECT_NE(tree.search(key), nullptr); + key = 10; EXPECT_NE(tree.search(key), nullptr); +} + +TEST(TBinSearchTreeTest, RemoveNodeWithTwoChildren) { + TBinSearchTree tree; + tree.insert(10, 10); + tree.insert(5, 5); + tree.insert(15, 15); + tree.insert(12, 12); + tree.insert(20, 20); + + int key = 15; + tree.remove(key); + EXPECT_EQ(tree.search(key), nullptr); + key = 12; EXPECT_NE(tree.search(key), nullptr); + key = 20; EXPECT_NE(tree.search(key), nullptr); + key = 10; EXPECT_NE(tree.search(key), nullptr); +} + +TEST(TBinSearchTreeTest, RemoveRoot) { + TBinSearchTree tree; + tree.insert(10, 10); + tree.insert(5, 5); + tree.insert(15, 15); + + int key = 10; + tree.remove(key); + EXPECT_EQ(tree.search(key), nullptr); + key = 5; EXPECT_NE(tree.search(key), nullptr); + key = 15; EXPECT_NE(tree.search(key), nullptr); +} + +TEST(TBinSearchTreeTest, DuplicateInsert) { + TBinSearchTree tree; + tree.insert(10, 10); + tree.insert(10, 10); // Duplicate + + // Tree should contain only one element 10 + int key = 10; + tree.remove(key); + EXPECT_EQ(tree.search(key), nullptr); +} + +TEST(TBinSearchTreeTest, Minimum) { + TBinSearchTree tree; + tree.insert(10, 10); + tree.insert(5, 5); + tree.insert(15, 15); + tree.insert(3, 3); + tree.insert(7, 7); + + // Find minimum through minimum() + auto* minNode = tree.minimum(); + EXPECT_NE(minNode, nullptr); + if (minNode) { + EXPECT_EQ(minNode->key, 3); + } +} + +TEST(TBinSearchTreeTest, CopyConstructor) { + TBinSearchTree tree; + // Вставляем пары (ключ, значение) + tree.insert(1, 10); + tree.insert(2, 5); + tree.insert(3, 15); + + TBinSearchTree treeCopy(tree); + + // Проверяем оригинальное дерево (ищем по ключам) + EXPECT_NE(tree.search(1), nullptr); + EXPECT_NE(tree.search(2), nullptr); + EXPECT_NE(tree.search(3), nullptr); + + // Проверяем значения в оригинальном дереве + EXPECT_EQ(tree.search(1)->value, 10); + EXPECT_EQ(tree.search(2)->value, 5); + EXPECT_EQ(tree.search(3)->value, 15); + + // Проверяем скопированное дерево (ищем по ключам) + EXPECT_NE(treeCopy.search(1), nullptr); + EXPECT_NE(treeCopy.search(2), nullptr); + EXPECT_NE(treeCopy.search(3), nullptr); + + // Проверяем значения в скопированном дереве + EXPECT_EQ(treeCopy.search(1)->value, 10); + EXPECT_EQ(treeCopy.search(2)->value, 5); + EXPECT_EQ(treeCopy.search(3)->value, 15); + + // Модифицируем копию и проверяем, что оригинал не изменился + treeCopy.remove(2); + EXPECT_EQ(treeCopy.search(2), nullptr); // В копии удалено + EXPECT_NE(tree.search(2), nullptr); // Оригинал не изменился + EXPECT_EQ(tree.search(2)->value, 5); // Значение в оригинале осталось +} \ No newline at end of file diff --git a/tests/test_dmassive.cpp b/tests/test_dmassive.cpp new file mode 100644 index 0000000..3e2f5cd --- /dev/null +++ b/tests/test_dmassive.cpp @@ -0,0 +1,439 @@ +// Copyright 2024 Anvar +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#define FRIEND_TEST_CASES +#include "../gtest/gtest.h" +#include "../lib_dmassive/archive.h" +#include <../main/utilites.h> + + + +TEST(Test_TDMassive, DefaultConstructor) { + TDMassive mas; + EXPECT_EQ(mas.size(), 0); + EXPECT_EQ(mas.capacity(), STEP_CAPACITY); + EXPECT_TRUE(mas.empty()); + EXPECT_FALSE(mas.full()); + EXPECT_NE(mas.data(), nullptr); + for (size_t i = 0; i < mas.capacity(); i++) { + EXPECT_EQ(mas.getState(i), State::empty); + } +} + +TEST(Test_TDMassive, CopyConstructor) { + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + TDMassive mas1(mas); + EXPECT_EQ(mas.size(), mas1.size()); + EXPECT_EQ(mas.capacity(), mas1.capacity()); + for (size_t i = 0; i < mas.size(); i++) { + EXPECT_EQ(mas.data()[i], mas1.data()[i]); + EXPECT_EQ(mas.getState(i), mas1.getState(i)); + } +} + +TEST(Test_TDMassive, InitializationConstructorFromArray) { + int arr[] = {1, 2, 3}; + size_t n = 3; + TDMassive mas(arr, n); + EXPECT_NE(mas.data(), nullptr); + EXPECT_FALSE(mas.empty()); + for (size_t i = 0; i < mas.size(); i++) { + EXPECT_EQ(mas.data()[i], arr[i]); + EXPECT_EQ(mas.getState(i), State::busy); + } + for (size_t i = mas.size(); i < mas.capacity(); i++) { + EXPECT_EQ(mas.getState(i), State::empty); + } +} + +TEST(Test_TDMassive, InitializationConstructorWithGivenSizeAndValue) { + int value = 42; + size_t n = 10; + TDMassive mas(n, value); + EXPECT_NE(mas.data(), nullptr); + EXPECT_FALSE(mas.empty()); + EXPECT_EQ(mas.size(), n); + EXPECT_EQ(mas.capacity(), (n > STEP_CAPACITY) ? n : STEP_CAPACITY); + for (size_t i = 0; i < mas.size(); i++) { + EXPECT_EQ(mas.data()[i], value); + EXPECT_EQ(mas.getState(i), State::busy); + } + for (size_t i = mas.size(); i < mas.capacity(); i++) { + EXPECT_EQ(mas.getState(i), State::empty); + } +} + +TEST(Test_TDMassive, RangeCopyConstructor) { + TDMassive mass; + mass.assign({1, 2}); + TDMassive copy(mass, 0, 1); + EXPECT_EQ(copy.size(), 1); + EXPECT_EQ(copy.capacity(), STEP_CAPACITY); + for (size_t i = 0; i < 2; ++i) { + EXPECT_EQ(copy.data()[i], mass.data()[i]); + EXPECT_EQ(copy.getState(i), mass.getState(i)); + } + for (size_t i = 2; i < copy.capacity(); ++i) { + EXPECT_EQ(copy.getState(i), State::empty); + } +} + +TEST(Test_TDMassive, Destructor) { + TDMassive mass; + { + TDMassive mass1; + } +} + +TEST(Test_TDMassive, empty_function) { + TDMassive mas; + EXPECT_TRUE(mas.empty()); + mas.push_back(1); + EXPECT_FALSE(mas.empty()); +} + +TEST(Test_TDMassive, full_function) { + TDMassive mas; + EXPECT_FALSE(mas.full()); + mas.resize(STEP_CAPACITY, 1); + EXPECT_TRUE(mas.full()); +} + +TEST(Test_TDMassive, get_size_function) { + TDMassive mas; + EXPECT_EQ(mas.size(), 0); + mas.push_back(1); + EXPECT_EQ(mas.size(), 1); + mas.push_back(2); + EXPECT_EQ(mas.size(), 2); +} + +TEST(Test_TDMassive, get_capacity_function) { + TDMassive mas; + EXPECT_EQ(mas.capacity(), STEP_CAPACITY); + mas.resize(STEP_CAPACITY + 1, 1); + EXPECT_GT(mas.capacity(), STEP_CAPACITY); +} + +TEST(Test_TDMassive, get_data_function) { + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + const int* data = mas.data(); + EXPECT_EQ(data[0], 1); + EXPECT_EQ(data[1], 2); +} + +TEST(Test_TDMassive, swap_function) { + TDMassive mass1; + mass1.push_back(1); + mass1.push_back(2); + mass1.push_back(3); + + TDMassive mass2; + mass2.push_back(4); + mass2.push_back(5); + + mass1.swap(mass2); + + EXPECT_EQ(mass1.size(), 2); + EXPECT_EQ(mass1.data()[0], 4); + EXPECT_EQ(mass1.data()[1], 5); + + EXPECT_EQ(mass2.size(), 3); + EXPECT_EQ(mass2.data()[0], 1); + EXPECT_EQ(mass2.data()[1], 2); + EXPECT_EQ(mass2.data()[2], 3); +} + +TEST(Test_TDMassive, assign_function) { + TDMassive mass1; + TDMassive mass2; + mass1.push_back(1); + mass1.push_back(2); + mass1.push_back(3); + mass1.push_back(4); + mass2.push_back(5); + mass2.push_back(6); + mass2.push_back(7); + mass2.push_back(8); + mass1.assign(mass2); + EXPECT_EQ(mass1.size(), mass2.size()); + EXPECT_EQ(mass1.capacity(), mass2.capacity()); + for (size_t i = 0; i < mass1.size(); ++i) { + EXPECT_EQ(mass1.data()[i], mass2.data()[i]); + EXPECT_EQ(mass1.getState(i), mass2.getState(i)); + } +} + +TEST(Test_TDMassive, clear_function) { + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.clear(); + EXPECT_TRUE(mas.empty()); + EXPECT_EQ(mas.capacity(), STEP_CAPACITY); +} + +TEST(Test_TDMassive, reserve_function) { + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + + size_t new_capacity = 10; + mas.reserve(new_capacity); + + EXPECT_GE(mas.capacity(), new_capacity); + EXPECT_EQ(mas.size(), 3); + EXPECT_EQ(mas.data()[0], 1); + EXPECT_EQ(mas.data()[1], 2); + EXPECT_EQ(mas.data()[2], 3); + + for (size_t i = 0; i < mas.size(); i++) { + EXPECT_EQ(mas.getState(i), State::busy); + } +} + +TEST(Test_TDMassive, resize_function) { + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + size_t newSize = 5; + int value = 42; + mas.resize(newSize, value); + EXPECT_EQ(mas.size(), newSize); + EXPECT_GE(mas.capacity(), newSize); + EXPECT_EQ(mas.data()[0], 1); + EXPECT_EQ(mas.data()[1], 2); + EXPECT_EQ(mas.data()[2], 3); + for (size_t i = 3; i < newSize; ++i) { + EXPECT_EQ(mas.data()[i], value); + EXPECT_EQ(mas.getState(i), State::busy); + } + mas.resize(2); + EXPECT_EQ(mas.size(), 2); + EXPECT_EQ(mas.data()[0], 1); + EXPECT_EQ(mas.data()[1], 2); +} + +TEST(Test_TDMassive, push_back_function) { + TDMassive mas; + if (mas.size() == mas.capacity()) { + mas.reserve(mas.capacity() + STEP_CAPACITY); + } + int value = 42; + mas.push_back(value); + EXPECT_EQ(mas.size(), 1); + EXPECT_EQ(mas.data()[0], value); + EXPECT_EQ(mas.getState(0), State::busy); +} + +TEST(Test_TDMassive, push_front_function) { + TDMassive mass(10); + mass.push_front(1); + mass.push_front(2); + mass.push_front(3); + + EXPECT_EQ(mass.data()[0], 3); + EXPECT_EQ(mass.data()[1], 2); + EXPECT_EQ(mass.data()[2], 1); + EXPECT_EQ(mass.size(), 3); +} + +TEST(Test_TDMassive, pop_front_function) { + TDMassive mass(10); + mass.push_back(1); + mass.push_back(2); + mass.push_back(3); + + mass.pop_front(); + EXPECT_EQ(mass.size(), 2); + EXPECT_EQ(mass.getState(0), State::deleted); + + + mass.pop_front(); + EXPECT_EQ(mass.size(), 1); + EXPECT_EQ(mass.getState(1), State::deleted); + + +} + +TEST(Test_TDMassive, pop_back_function) { + TDMassive mass; + mass.push_back(1); + mass.push_back(2); + mass.push_back(3); + + mass.pop_back(); + EXPECT_EQ(mass.size(), 2); + EXPECT_EQ(mass[0], 1); + EXPECT_EQ(mass[1], 2); + + mass.pop_back(); + EXPECT_EQ(mass.size(), 1); + EXPECT_EQ(mass[0], 1); + + mass.pop_back(); + EXPECT_EQ(mass.size(), 0); +} + +TEST(Test_TDMassive, insert_array_function) { + int arr[] = {1, 2, 3, 4, 5}; + TDMassive mas; + mas.insert(arr, 5, 0); + EXPECT_EQ(mas.size(), 5); + for (size_t i = 0; i < mas.size(); ++i) { + EXPECT_EQ(mas.data()[i], arr[i]); + } +} + +TEST(Test_TDMassive, insert_at_position_function) { + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + mas.insert(4, 2); + EXPECT_EQ(mas.size(), 4); + EXPECT_EQ(mas.data()[0], 1); + EXPECT_EQ(mas.data()[1], 2); + EXPECT_EQ(mas.data()[2], 4); + EXPECT_EQ(mas.data()[3], 3); + EXPECT_EQ(mas.getState(2), State::busy); +} + +TEST(Test_TDMassive, replace_function) { + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + mas.replace(2, 4); + EXPECT_EQ(mas.size(), 3); + EXPECT_EQ(mas.data()[0], 1); + EXPECT_EQ(mas.data()[1], 2); + EXPECT_EQ(mas.data()[2], 4); + EXPECT_EQ(mas.getState(2), State::busy); +} + +TEST(Test_TDMassive, erase_function) { + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + mas.erase(0, 1); + EXPECT_EQ(mas.size(), 2); + EXPECT_EQ(mas.data()[0], 2); + EXPECT_EQ(mas.data()[1], 3); + EXPECT_EQ(mas.getState(1), State::busy); +} + +TEST(Test_TDMassive, remove_all_function) { + int value = 2; + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + mas.remove_all(value); + EXPECT_EQ(mas.size(), 2); + EXPECT_EQ(mas.data()[0], 1); + EXPECT_EQ(mas.data()[1], 3); + EXPECT_EQ(mas.getState(1), State::busy); +} + +TEST(Test_TDMassive, remove_first_function) { + int value = 2; + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + mas.push_back(2); + mas.remove_first(value); + EXPECT_EQ(mas.size(), 3); + EXPECT_EQ(mas.data()[0], 1); + EXPECT_EQ(mas.data()[1], 3); + EXPECT_EQ(mas.data()[2], 2); + EXPECT_EQ(mas.getState(1), State::busy); +} + +TEST(Test_TDMassive, remove_last_function) { + int value = 2; + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + mas.remove_last(value); + EXPECT_EQ(mas.size(), 2); + EXPECT_EQ(mas.data()[0], 1); + EXPECT_EQ(mas.data()[1], 3); + EXPECT_EQ(mas.getState(1), State::busy); +} + +TEST(Test_TDMassive, remove_by_index_function) { + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + mas.remove_by_index(1); + EXPECT_EQ(mas.size(), 2); + EXPECT_EQ(mas.data()[0], 1); + EXPECT_EQ(mas.data()[1], 3); + EXPECT_EQ(mas.getState(1), State::busy); +} + +TEST(Test_TDMassive, find_all_function) { +TDMassive mass(10); + mass.push_back(1); + mass.push_back(2); + mass.push_back(1); + mass.push_back(3); + + size_t* result = mass.find_all(1); + EXPECT_EQ(result[0], 2); + EXPECT_EQ(result[1], 0); + EXPECT_EQ(result[2], 2); + delete[] result; + + result = mass.find_all(2); + EXPECT_EQ(result[0], 1); + EXPECT_EQ(result[1], 1); + delete[] result; + + result = mass.find_all(3); + EXPECT_EQ(result[0], 1); + EXPECT_EQ(result[1], 3); + delete[] result; +} + +TEST(Test_TDMassive, find_first_function) { + int value = 2; + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + size_t pos = mas.find_first(value); + EXPECT_EQ(mas.getState(pos), State::busy); +} + +TEST(Test_TDMassive, find_last_function) { + int value = 2; + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + size_t pos = mas.find_last(value); + EXPECT_EQ(mas.getState(pos), State::busy); +} + +TEST(Test_TDMassive, get_state_function) { + TDMassive mas; + mas.push_back(1); + mas.push_back(2); + mas.push_back(3); + + EXPECT_EQ(mas.getState(0), State::busy); + EXPECT_EQ(mas.getState(1), State::busy); + EXPECT_EQ(mas.getState(2), State::busy); +} diff --git a/tests/test_dsu.cpp b/tests/test_dsu.cpp new file mode 100644 index 0000000..1abe092 --- /dev/null +++ b/tests/test_dsu.cpp @@ -0,0 +1,45 @@ +// Copyright 2024 Anvar +#include "../lib_dsu/dsu.h" +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#include "../gtest/gtest.h" +#include +#include + +TEST(DSU, TestMakeSet) { + DSU dsu(10); + dsu.make_set(5); + EXPECT_EQ(dsu.find(5), 5); +} + +TEST(DSU, TestFind) { + DSU dsu(10); + dsu.make_set(5); + dsu.make_set(6); + dsu.union_sets(5, 6); + EXPECT_EQ(dsu.find(5), dsu.find(6)); +} + +TEST(DSU, TestUnionSets) { + DSU dsu(10); + dsu.make_set(1); + dsu.make_set(2); + dsu.make_set(3); + dsu.union_sets(1, 2); + dsu.union_sets(2, 3); + EXPECT_EQ(dsu.find(1), dsu.find(2)); + EXPECT_EQ(dsu.find(2), dsu.find(3)); +} + +TEST(DSU, TestClear) { + DSU dsu(10); + dsu.make_set(1); + dsu.make_set(2); + dsu.union_sets(1, 2); + dsu.clear(); + EXPECT_THROW(dsu.find(1), std::logic_error); +} + +TEST(DSU, TestOutOfRange) { + DSU dsu(10); + EXPECT_THROW(dsu.find(10), std::logic_error); +} diff --git a/tests/test_easy_example.cpp b/tests/test_easy_example.cpp index 2fa01a9..b4f5736 100644 --- a/tests/test_easy_example.cpp +++ b/tests/test_easy_example.cpp @@ -1,5 +1,5 @@ // Copyright 2024 Marina Usova - +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING #include #include "../lib_easy_example/easy_example.h" diff --git a/tests/test_heap.cpp b/tests/test_heap.cpp new file mode 100644 index 0000000..3d3809f --- /dev/null +++ b/tests/test_heap.cpp @@ -0,0 +1,206 @@ +// Copyright 2024 Anvar + +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#define FRIEND_TEST_CASES +#include "../gtest/gtest.h" +#include "../lib_heap/heap.h" + +TEST(Heap_Test, Parent_func_test){ + Heap heap(10); + heap.push_heap(1); + + EXPECT_EQ(heap.parent(1), 0); + EXPECT_EQ(heap.parent(2), 0); + EXPECT_EQ(heap.parent(3), 1); + EXPECT_EQ(heap.parent(4), 1); + EXPECT_EQ(heap.parent(0), 0); +} +TEST(Heap_Test, Left_Child_func_test){ + Heap heap(10); + heap.push_heap(1); + + EXPECT_EQ(heap.left_child(1), 3); + EXPECT_EQ(heap.left_child(2), 5); + EXPECT_EQ(heap.left_child(3), 7); + EXPECT_EQ(heap.left_child(4), 9); + EXPECT_EQ(heap.left_child(0), 1); +} +TEST(Heap_Test, Right_Child_func_test){ + Heap heap(10); + heap.push_heap(1); + + EXPECT_EQ(heap.right_child(1), 4); + EXPECT_EQ(heap.right_child(2), 6); + EXPECT_EQ(heap.right_child(3), 8); + EXPECT_EQ(heap.right_child(4), 10); + EXPECT_EQ(heap.right_child(0), 2); +} +TEST(HeapTest, ResizeFunctionalTest) { + Heap heap(2); + + // Проверяем начальное состояние + ASSERT_TRUE(heap.is_empty()); + + // Добавляем элементы + heap.push_heap(1); + ASSERT_EQ(heap.top(), 1); // После первого элемента top() должен вернуть 1 + + heap.push_heap(2); + ASSERT_EQ(heap.top(), 2); // В max-heap новый максимальный элемент 2 + + heap.push_heap(3); + ASSERT_EQ(heap.top(), 3); // Теперь максимальный элемент 3 + + // Извлекаем элементы и проверяем порядок + EXPECT_EQ(heap.top(), 3); + heap.pop_heap(); + + EXPECT_EQ(heap.top(), 2); + heap.pop_heap(); + + EXPECT_EQ(heap.top(), 1); + heap.pop_heap(); + + ASSERT_TRUE(heap.is_empty()); // Куча должна быть пуста + +} + +TEST(HeapTest, DefaultConstructor) { + Heap heap(0); + EXPECT_TRUE(heap.is_empty()); + +} + +TEST(HeapTest, CapacityConstructor) { + Heap heap(5); + EXPECT_TRUE(heap.is_empty()); + EXPECT_NO_THROW(heap.push_heap(10)); +} +TEST(HeapTest, CopyConstructor) { + Heap heap1(2); + heap1.push_heap(10); + heap1.push_heap(20); + + Heap heap2(heap1); + EXPECT_EQ(heap2.top(), 20); + heap2.pop_heap(); + EXPECT_EQ(heap2.top(), 10); +} +TEST(HeapTest, MoveConstructor) { + Heap heap1(2); + heap1.push_heap(10); + heap1.push_heap(20); + + Heap heap2(std::move(heap1)); + EXPECT_EQ(heap2.top(), 20); + heap2.pop_heap(); + EXPECT_EQ(heap2.top(), 10); + +} + +TEST(HeapTest, PushHeap) { + Heap heap(2); + heap.push_heap(10); + EXPECT_EQ(heap.top(), 10); + heap.push_heap(20); + EXPECT_EQ(heap.top(), 20); + heap.push_heap(5); + EXPECT_EQ(heap.top(), 20); // 20 остается наверху в max-heap + +} + +TEST(HeapTest, PopHeap) { + Heap heap(3); + heap.push_heap(10); + heap.push_heap(20); + heap.push_heap(5); + + EXPECT_EQ(heap.top(), 20); + heap.pop_heap(); + EXPECT_EQ(heap.top(), 10); + heap.pop_heap(); + EXPECT_EQ(heap.top(), 5); + heap.pop_heap(); + EXPECT_TRUE(heap.is_empty()); + EXPECT_THROW(heap.pop_heap(), std::out_of_range); // Попытка извлечь из пустой кучи +} + +TEST(HeapTest, Emplace) { + Heap heap(10); + heap.push_heap(10); + heap.push_heap(20); + heap.push_heap(30); + + // Заменяем элемент с индексом 1 (значение 20) на 40 + heap.emplace(1, 40); + EXPECT_EQ(heap.top(), 40); // Теперь 40 должно быть наверху + + + heap.emplace(0, 5); + EXPECT_EQ(heap.top(), 30); // Теперь 30 должно всплыть наверх + + // Попытка заменить несуществующий индекс + EXPECT_THROW(heap.emplace(10, 100), std::out_of_range); +} + +TEST(HeapTest, Top) { + Heap heap(10); + EXPECT_THROW(heap.top(), std::out_of_range); // Пустая куча + + heap.push_heap(10); + EXPECT_EQ(heap.top(), 10); + + heap.push_heap(20); + EXPECT_EQ(heap.top(), 20); + + heap.pop_heap(); + EXPECT_EQ(heap.top(), 10); +} + +TEST(HeapTest, IsEmpty) { + Heap heap(10); + EXPECT_TRUE(heap.is_empty()); + + heap.push_heap(10); + EXPECT_FALSE(heap.is_empty()); + + heap.pop_heap(); + EXPECT_TRUE(heap.is_empty()); +} + +TEST(HeapTest, MinHeap) { + Heap minHeap(10); + + minHeap.push_heap(10); + minHeap.push_heap(20); + minHeap.push_heap(5); + + EXPECT_EQ(minHeap.top(), 5); // В min-heap минимальный элемент наверху + minHeap.pop_heap(); + EXPECT_EQ(minHeap.top(), 10); + minHeap.pop_heap(); + EXPECT_EQ(minHeap.top(), 20); + minHeap.pop_heap(); + EXPECT_TRUE(minHeap.is_empty()); +} + +TEST(HeapTest, HeapifyUp) { + Heap heap(10); + heap.emplace(0, 10); + heap.emplace(1, 20); // Этот элемент должен всплыть наверх + heap.emplace(2, 15); + + // Проверяем, что heapify_up корректно работает + EXPECT_EQ(heap.top(), 20); +} + +TEST(HeapTest, HeapifyDown) { + Heap heap(10); + // Вручную создаем ситуацию, когда корень не максимальный + heap.emplace(0, 10); + heap.emplace(1, 5); + heap.emplace(2, 15); + + // Проверяем, что heapify_down корректно работает + EXPECT_EQ(heap.top(), 15); // 15 должно всплыть наверх +} \ No newline at end of file diff --git a/tests/test_list.cpp b/tests/test_list.cpp new file mode 100644 index 0000000..bd30a6d --- /dev/null +++ b/tests/test_list.cpp @@ -0,0 +1,168 @@ +// Copyright 2024 Anvar +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#include "../gtest/gtest.h" +#include "../lib_list/list.h" + + +TEST(TListTest, DefaultConstructorTNode) { + TNode node(5, nullptr); + EXPECT_EQ(node.value, 5); + EXPECT_EQ(node.pnext, nullptr); +} +TEST(TListTest, ParameterizedConstructorTNode) { + TNode node(5, nullptr); + EXPECT_EQ(node.value, 5); + EXPECT_EQ(node.pnext, nullptr); +} +TEST(TListTest, CopyConstructorTNode) { + TNode node1(5, nullptr); + TNode node2(node1); + EXPECT_EQ(node2.value, 5); + EXPECT_EQ(node2.pnext, nullptr); +} +TEST(TListTest, DistructorTNode) { + TNode node(5, nullptr); +} +TEST(TListTest, OperatorQuallyTNode) { + TNode node1(5, nullptr); + TNode node2; + node2 = node1; + EXPECT_EQ(node2.value, 5); + EXPECT_EQ(node2.pnext, nullptr); +} +TEST(TListTest, SetNextTNode) { + TNode node1(5, nullptr); + TNode node2(10, nullptr); + node1.next(&node2); + EXPECT_EQ(node1.pnext, &node2); +} +TEST(TListTest, GetValueTNode) { + TNode node1(5, nullptr); + EXPECT_EQ(node1.value, 5); +} +TEST(TListTest, SetValueTNode) { + TNode node1(5, nullptr); + node1.value = 10; + EXPECT_EQ(node1.value, 10); +} + +TEST(TListTest, DefaultConstructor) { + TList list; + EXPECT_TRUE(list.isEmpty()); + EXPECT_EQ(list.head, nullptr); + EXPECT_EQ(list.tail, nullptr); +} + +TEST(TListTest, CopyConstructor) { + TList list1; + list1.push_back(1); + list1.push_back(2); + list1.push_back(3); + + TList list2(list1); + EXPECT_FALSE(list2.isEmpty()); + EXPECT_EQ(list2.head->value, 1); + EXPECT_EQ(list2.tail->value, 3); +} + +TEST(TListTest, PushFront) { + TList list; + list.push_front(1); + list.push_front(2); + list.push_front(3); + EXPECT_EQ(list.head->value, 3); + EXPECT_EQ(list.tail->value, 1); +} + +TEST(TListTest, PushBack) { + TList list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + EXPECT_EQ(list.head->value, 1); + EXPECT_EQ(list.tail->value, 3); +} + +TEST(TListTest, Insert) { + TList list; + list.push_back(1); + list.push_back(3); + list.insert(1, 2); + EXPECT_EQ(list.head->value, 1); + EXPECT_EQ(list.head->pnext->value, 2); + EXPECT_EQ(list.tail->value, 3); +} + +TEST(TListTest, InsertAfter) { + TList list; + list.push_back(1); + list.push_back(3); + list.insertAfter(2, 1); + EXPECT_EQ(list.head->value, 1); + EXPECT_EQ(list.head->pnext->value, 2); + EXPECT_EQ(list.tail->value, 3); +} + +TEST(TListTest, InsertAt) { + TList list; + list.push_back(1); + list.push_back(3); + list.insertAt(2, 1); + EXPECT_EQ(list.head->value, 1); + EXPECT_EQ(list.head->pnext->value, 2); + EXPECT_EQ(list.tail->value, 3); +} + +TEST(TListTest, Find) { + TList list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + TNode* node = list.find(2); + EXPECT_NE(node, nullptr); + EXPECT_EQ(node->value, 2); +} + +TEST(TListTest, RemoveValue) { + TList list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.removeValue(2); + EXPECT_EQ(list.head->value, 1); + EXPECT_EQ(list.tail->value, 3); +} + +TEST(TListTest, RemoveAt) { + TList list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.removeAt(1); + EXPECT_EQ(list.head->value, 1); + EXPECT_EQ(list.tail->value, 3); +} + +TEST(TListTest, Erase) { + TList list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + TNode* node = list.head->pnext; + list.erase(node); + EXPECT_EQ(list.head->value, 1); + EXPECT_EQ(list.tail->value, 3); +} + +TEST(TListTest, Replace) { + TList list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.replace(1, 4); + EXPECT_EQ(list.head->value, 1); + EXPECT_EQ(list.head->pnext->value, 4); + EXPECT_EQ(list.tail->value, 3); +} + + diff --git a/tests/test_matrix.cpp b/tests/test_matrix.cpp new file mode 100644 index 0000000..ea697e1 --- /dev/null +++ b/tests/test_matrix.cpp @@ -0,0 +1,118 @@ +// Copyright 2024 Anvar +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#define FRIEND_TEST_CASES + +#include "../gtest/gtest.h" + +#include "../lib_matrix/matrix.h" + +/* TEST(TUpperTriangularMatrixTest, DefaultConstructor) { + TUpperTriangularMatrix m(3); + EXPECT_EQ(m.size(), 3); + EXPECT_EQ(m[0][0], 0); + EXPECT_EQ(m[1][1], 0); + EXPECT_EQ(m[2][2], 0); +} + +TEST(TUpperTriangularMatrixTest, ConstructorFromArray) { + int arr[6] = {1, 2, 3, 4, 5, 6}; + TUpperTriangularMatrix m(arr, 3); + EXPECT_EQ(m[0][0], 1); + EXPECT_EQ(m[0][1], 2); + EXPECT_EQ(m[1][1], 4); + EXPECT_EQ(m[2][2], 6); +} + +TEST(TUpperTriangularMatrixTest, CopyConstructor) { + TUpperTriangularMatrix m1(3); + m1[0][0] = 1; + TUpperTriangularMatrix m2 = m1; + EXPECT_EQ(m1[0][0], m2[0][0]); + EXPECT_EQ(m1[1][1], m2[1][1]); + EXPECT_EQ(m1[2][2], m2[2][2]); +} + +TEST(TUpperTriangularMatrixTest, AdditionOperator) { + TUpperTriangularMatrix m1(3); + TUpperTriangularMatrix m2(3); + m1[0][0] = 1; + m2[0][0] = 2; + TUpperTriangularMatrix m3 = m1 + m2; + EXPECT_EQ(m3[0][0], 3); + EXPECT_EQ(m3[1][1], 0); + EXPECT_EQ(m3[2][2], 0); +} + +TEST(TUpperTriangularMatrixTest, AdditionAssignmentOperator) { + TUpperTriangularMatrix m1(3); + TUpperTriangularMatrix m2(3); + m1[0][0] = 1; + m2[0][0] = 2; + m1 += m2; + EXPECT_EQ(m1[0][0], 3); + EXPECT_EQ(m1[1][1], 0); + EXPECT_EQ(m1[2][2], 0); +} + +TEST(TUpperTriangularMatrixTest, MultiplicationOperator) { + TUpperTriangularMatrix m1(3); + m1[0][0] = 1; + m1[0][1] = 2; + m1[1][1] = 3; + TUpperTriangularMatrix m2(3); + m2[0][0] = 4; + m2[1][1] = 5; + TUpperTriangularMatrix m3 = m1 * m2; + EXPECT_EQ(m3[0][0], 4); + EXPECT_EQ(m3[0][1], 10); + EXPECT_EQ(m3[1][1], 15); +} + +TEST(TUpperTriangularMatrixTest, MultiplicationByScalar) { + TUpperTriangularMatrix m(3); + m[0][0] = 1; + TUpperTriangularMatrix result = m * 2; + EXPECT_EQ(result[0][0], 2); + EXPECT_EQ(result[1][1], 0); + EXPECT_EQ(result[2][2], 0); +} + +TEST(TUpperTriangularMatrixTest, DivisionByScalar) { + TUpperTriangularMatrix m(3); + m[0][0] = 4; + TUpperTriangularMatrix result = m / 2; + EXPECT_EQ(result[0][0], 2); + EXPECT_EQ(result[1][1], 0); + EXPECT_EQ(result[2][2], 0); +} +TEST(TUpperTriangularMatrixTest, DivisionByZeroThrowsException) { + TUpperTriangularMatrix m(3); + m[0][0] = 4; + EXPECT_THROW(m / 0, std::invalid_argument); +} + + + +TEST(TUpperTriangularMatrixTest, ToUpperTriangular) { + TDMassive matrix(3); + matrix[0][0] = -1; + matrix[0][1] = 1; + matrix[0][2] = 3; + matrix[1][1] = 4; + matrix[0][1] = 4; + + + TDMassive upperTriangular = to_upper_triangular(matrix, 3); + + EXPECT_EQ(upperTriangular[0][0], 1); + EXPECT_EQ(upperTriangular[1][1], 2); + EXPECT_EQ(upperTriangular[2][2], 3); +} + +// Тест вывода в поток +TEST(TUpperTriangularMatrixTest, OutputStream) { + TUpperTriangularMatrix m(3); + std::ostringstream oss; + oss << m; + EXPECT_EQ(oss.str(), "0 0 0 \n0 0 0 \n0 0 0 \n"); +} */ \ No newline at end of file diff --git a/tests/test_merge_sorted_lists.cpp b/tests/test_merge_sorted_lists.cpp new file mode 100644 index 0000000..ae1b3b6 --- /dev/null +++ b/tests/test_merge_sorted_lists.cpp @@ -0,0 +1,44 @@ +// Copyright 2024 Anvar +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#define FRIEND_TEST_CASES +#include "../gtest/gtest.h" +#include "../lib_merge_sorted_lists/merge_sorted_lists.h" + +TEST(MergeSortedListsTest, BothListsEmpty) { + std::list list1; + std::list list2; + std::list result = mergeSortedLists(list1, list2); + EXPECT_TRUE(result.empty()); +} + +TEST(MergeSortedListsTest, FirstListEmpty) { + std::list list1; + std::list list2 = {1, 3, 5}; + std::list result = mergeSortedLists(list1, list2); + std::list expected = {1, 3, 5}; + EXPECT_EQ(result, expected); +} + +TEST(MergeSortedListsTest, SecondListEmpty) { + std::list list1 = {2, 4, 6}; + std::list list2; + std::list result = mergeSortedLists(list1, list2); + std::list expected = {2, 4, 6}; + EXPECT_EQ(result, expected); +} + +TEST(MergeSortedListsTest, BothListsNonEmpty) { + std::list list1 = {1, 3, 5}; + std::list list2 = {2, 4, 6}; + std::list result = mergeSortedLists(list1, list2); + std::list expected = {1, 2, 3, 4, 5, 6}; + EXPECT_EQ(result, expected); +} + +TEST(MergeSortedListsTest, ListsWithDuplicates) { + std::list list1 = {1, 3, 5, 7}; + std::list list2 = {2, 3, 4, 6}; + std::list result = mergeSortedLists(list1, list2); + std::list expected = {1, 2, 3, 3, 4, 5, 6, 7}; + EXPECT_EQ(result, expected); +} \ No newline at end of file diff --git a/tests/test_pair.cpp b/tests/test_pair.cpp new file mode 100644 index 0000000..c6cacf4 --- /dev/null +++ b/tests/test_pair.cpp @@ -0,0 +1,35 @@ +// Copyright 2024 Anvar +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#include "../gtest/gtest.h" +#include "../lib_pair/pair.h" + +TEST(TPairTest, First) { + TPair pair(42, "hello"); + EXPECT_EQ(42, pair.first()); +} +TEST(TPairTest, Second) { + TPair pair(42, 43); + EXPECT_EQ(43, pair.second()); +} +TEST(TPairTest, SetFirst) { + int value = 42; + TPair pair(43, 44); + pair.set_first(value); + EXPECT_EQ(42, pair.first()); +} +TEST(TPairTest, SetSecond) { + int value = 42; + TPair pair(43, 44); + pair.set_second(value); + EXPECT_EQ(42, pair.second()); +} + +TEST(TPairTest, Swap) { + TPair pair1(10, 20); + TPair pair2(30, 40); + pair1.swap(pair2); + EXPECT_EQ(pair1.first(), 30); + EXPECT_EQ(pair1.second(), 40); + EXPECT_EQ(pair2.first(), 10); + EXPECT_EQ(pair2.second(), 20); +} \ No newline at end of file diff --git a/tests/test_queue.cpp b/tests/test_queue.cpp new file mode 100644 index 0000000..534be66 --- /dev/null +++ b/tests/test_queue.cpp @@ -0,0 +1,94 @@ +// Copyright 2024 Anvar +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#include <../gtest/gtest.h> +#include "../lib_queue/queue.h" + +TEST(TQueueTests, DefaultConstructor) { + TQueue que; + EXPECT_TRUE(que.empty()); + EXPECT_EQ(que.size(), 0); +} +TEST(TQueueTests, CopyConstructor) { + TQueue que; + que.push_back(1); + TQueue que2(que); + EXPECT_FALSE(que2.empty()); + EXPECT_EQ(que2.size(), 1); +} +TEST(TQueueTests,OperatorQually) { + TQueue que; + que.push_back(1); + que.push_back(2); + TQueue que2; ; + que2 = que; + EXPECT_EQ(que2.front(),que.front()); + EXPECT_FALSE(que2.empty()); + EXPECT_EQ(que2.size(), 2); + +} +TEST(TQueueTests, Distructor) { + TQueue que; + +} +TEST(TQueueTests, PushBack) { + TQueue que; + que.push_back(1); + que.push_back(2); + que.push_back(3); + EXPECT_FALSE(que.empty()); + EXPECT_EQ(que.size(), 3); +} +TEST(TQueueTests, PopFront) { + TQueue que; + que.push_back(1); + que.push_back(2); + que.push_back(3); + que.pop_front(); + EXPECT_EQ(que.front(), 2); + EXPECT_FALSE(que.empty()); + EXPECT_EQ(que.size(), 2); +} +TEST(TQueueTests, Front) { + TQueue que; + que.push_back(1); + que.push_back(2); + que.push_back(3); + EXPECT_EQ(que.front(), 1); + EXPECT_FALSE(que.empty()); + EXPECT_EQ(que.size(), 3); +} +TEST(TQueueTests, Empty) { + TQueue que; + que.push_back(1); + que.push_back(2); + que.push_back(3); + EXPECT_FALSE(que.empty()); + que.pop_front(); + que.pop_front(); + que.pop_front(); + EXPECT_TRUE(que.empty()); +} +TEST(TQueueTests, Size) { + TQueue que; + que.push_back(1); + que.push_back(2); + que.push_back(3); + EXPECT_FALSE(que.empty()); + EXPECT_EQ(que.size(), 3); + que.pop_front(); + EXPECT_EQ(que.size(), 2); +} +TEST(TQueueTests, Print) { + TQueue que; + que.push_back(1); + que.push_back(2); + que.push_back(3); + que.print(); +} + + + + + + + diff --git a/tests/test_stack.cpp b/tests/test_stack.cpp new file mode 100644 index 0000000..64a3e2e --- /dev/null +++ b/tests/test_stack.cpp @@ -0,0 +1,88 @@ +// Copyright 2024 Anvar + +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING + +#include "../gtest/gtest.h" +#include "../lib_stack/stack.h" + +TEST(TStackTests, DefaultConstructor) { + TStack sta; + EXPECT_TRUE(sta.empty()); + EXPECT_EQ(sta.size(), 0); +} +TEST(TStackTests, CopyConstructor) { + TStack sta; + sta.push(1); + TStack sta2(sta); + EXPECT_FALSE(sta2.empty()); + EXPECT_EQ(sta2.size(), 1); +} +TEST(TStackTests,OperatorQually) { + TStack sta; + sta.push(1); + sta.push(2); + TStack sta2 ; + sta2 = sta; + EXPECT_EQ(sta2.top(),sta.top()); + EXPECT_FALSE(sta2.empty()); + EXPECT_EQ(sta2.size(), 2); + +} +TEST(TStackTests, Distructor) { + TStack sta; + +} +TEST(TStackTests, Push) { + TStack sta; + sta.push(1); + sta.push(2); + EXPECT_EQ(sta.size(), 2); + EXPECT_EQ(sta.top(), 2); +} +TEST(TStackTests, Pop) { + TStack sta; + sta.push(1); + sta.push(2); + sta.push(3); + sta.pop(); + EXPECT_EQ(sta.size(), 2); + EXPECT_EQ(sta.top(), 2); + sta.pop(); + EXPECT_EQ(sta.size(), 1); + EXPECT_EQ(sta.top(), 1); + sta.pop(); + EXPECT_TRUE(sta.empty()); +} +TEST(TStackTests, Top) { + TStack sta; + sta.push(1); + sta.push(2); + sta.push(3); + EXPECT_EQ(sta.top(), 3); +} +TEST(TStackTests, Empty) { + TStack sta; + sta.push(1); + sta.push(2); + sta.push(3); + EXPECT_FALSE(sta.empty()); + sta.pop(); + sta.pop(); + sta.pop(); + EXPECT_TRUE(sta.empty()); + +} +TEST(TStackTests, Size) { + TStack sta; + sta.push(1); + sta.push(2); + sta.push(3); + EXPECT_EQ(sta.size(), 3); +} +TEST(TStackTests, Print) { + TStack sta; + sta.push(1); + sta.push(2); + sta.push(3); + sta.print(); +} diff --git a/tests/test_tbst_table.cpp b/tests/test_tbst_table.cpp new file mode 100644 index 0000000..17033da --- /dev/null +++ b/tests/test_tbst_table.cpp @@ -0,0 +1,131 @@ +/* // Copyright 2024 Anvar +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#define FRIEND_TEST_CASES +#include "../gtest/gtest.h" +#include "../lib_tbsttable/tbst_table.h" +#include "../lib_itable/itable.h" +TEST(TBSTableTest, InsertAndFind) { + TBSTable table; + + // Проверка пустой таблицы + EXPECT_TRUE(table.isEmpty()); + EXPECT_EQ(table.find(1), nullptr); + EXPECT_FALSE(table.contains(1)); + EXPECT_EQ(table.size(), 0); + + // Вставка элементов + table.insert(1, "one"); + table.insert(2, "two"); + table.insert(3, "three"); + + // Проверка наличия элементов + EXPECT_FALSE(table.isEmpty()); + EXPECT_NE(table.find(1), nullptr); + EXPECT_EQ(*table.find(1), "one"); + EXPECT_NE(table.find(2), nullptr); + EXPECT_EQ(*table.find(2), "two"); + EXPECT_NE(table.find(3), nullptr); + EXPECT_EQ(*table.find(3), "three"); + EXPECT_TRUE(table.contains(1)); + EXPECT_TRUE(table.contains(2)); + EXPECT_TRUE(table.contains(3)); + EXPECT_FALSE(table.contains(4)); +} + +TEST(TBSTableTest, Remove) { + TBSTable table; + table.insert(1, "one"); + table.insert(2, "two"); + table.insert(3, "three"); + + // Удаление существующего элемента + EXPECT_TRUE(table.remove(2)); + EXPECT_FALSE(table.contains(2)); + EXPECT_EQ(table.find(2), nullptr); + EXPECT_TRUE(table.contains(1)); + EXPECT_TRUE(table.contains(3)); + + // Удаление несуществующего элемента + EXPECT_FALSE(table.remove(99)); +} + +TEST(TBSTableTest, UpdateValue) { + TBSTable table; + table.insert(1, "one"); + + // Обновление значения + table.insert(1, "updated one"); + EXPECT_NE(table.find(1), nullptr); + EXPECT_EQ(*table.find(1), "updated one"); +} + +TEST(TBSTableTest, ConstFind) { + TBSTable table; + table.insert(1, "one"); + table.insert(2, "two"); + + // Проверка константного метода find + const auto& constTable = table; + const std::string* value = constTable.find(1); + EXPECT_NE(value, nullptr); + EXPECT_EQ(*value, "one"); + EXPECT_EQ(constTable.find(3), nullptr); +} + +TEST(TBSTableTest, Items) { + TBSTable table; + table.insert(3, "three"); + table.insert(1, "one"); + table.insert(2, "two"); + + auto items = table.items(); + EXPECT_EQ(items.size(), 3); + + // Проверяем наличие всех элементов + EXPECT_TRUE(VectorContains(items, TPair(1, "one"))); + EXPECT_TRUE(VectorContains(items, TPair(2, "two"))); + EXPECT_TRUE(VectorContains(items, TPair(3, "three"))); +} + +TEST(TBSTableTest, ComplexTypes) { + TBSTable> table; + + // Проверка работы со сложными типами + TVector vec1; + vec1.push_back(1); + vec1.push_back(2); + vec1.push_back(3); + + TVector vec2; + vec2.push_back(4); + vec2.push_back(5); + vec2.push_back(6); + + table.insert("first", vec1); + table.insert("second", vec2); + + EXPECT_NE(table.find("first"), nullptr); + EXPECT_EQ(table.find("first")->size(), 3u); + EXPECT_EQ((*table.find("first"))[0], 1); + + EXPECT_NE(table.find("second"), nullptr); + EXPECT_EQ(table.find("second")->size(), 3u); + EXPECT_EQ((*table.find("second"))[2], 6); +} + +TEST(TBSTableTest, Size) { + TBSTable table; + EXPECT_EQ(table.size(), 0); + + table.insert(1, "one"); + EXPECT_EQ(table.size(), 1); + + table.insert(2, "two"); + EXPECT_EQ(table.size(), 2); + + table.remove(1); + EXPECT_EQ(table.size(), 1); + + table.remove(2); + EXPECT_EQ(table.size(), 0); +} */ \ No newline at end of file diff --git a/tests/test_unsorted_table_list.cpp b/tests/test_unsorted_table_list.cpp new file mode 100644 index 0000000..7fe9163 --- /dev/null +++ b/tests/test_unsorted_table_list.cpp @@ -0,0 +1,39 @@ +/* // Copyright 2024 Anvar +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#define FRIEND_TEST_CASES + +#include "../gtest/gtest.h" +#include "../lib_itable/unsorted_table_list.h" +#include "../lib_itable/itable.h" + +TEST(TUnsortedTableTest, InsertAndUpdateValue) { + TUnsortedTable table; + + // 1. Проверка пустой таблицы + int* found = table.Find(1); + ASSERT_EQ(found, nullptr); + + // 2. Вставка нового элемента + table.Insert(1, 100); + + // Проверка вставки + found = table.Find(1); + ASSERT_NE(found, nullptr); // Проверяем, что указатель не nullptr + ASSERT_EQ(*found, 100); // Проверяем значение через разыменование + + // 3. Обновление значения + table.Insert(1, 200); + + // Проверка обновления + found = table.Find(1); + ASSERT_NE(found, nullptr); + ASSERT_EQ(*found, 200); // Проверяем новое значение + + // 4. Проверка размера + ASSERT_EQ(table.Size(), 1); + + // 5. Проверка удаления + table.Remove(1); + ASSERT_EQ(table.Find(1), nullptr); + ASSERT_EQ(table.Size(), 0); +} */ \ No newline at end of file diff --git a/tests/test_vector.cpp b/tests/test_vector.cpp new file mode 100644 index 0000000..8c1708c --- /dev/null +++ b/tests/test_vector.cpp @@ -0,0 +1,448 @@ +// Copyright 2024 Anvar +#define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING +#include +#include "../lib_vector/vector.h" + +TEST(TVectorTest, DefaultConstructor) { + TVector vec; + EXPECT_EQ(vec.size(), 0); +} +TEST(TVectorTest, FillConstructor) { + TVector vec(8, 4); + EXPECT_TRUE(vec.empty()); + EXPECT_EQ(vec.size(), 0); +} +TEST(TVectorTest, ConstructorWithTwoArguments) { + TVector vec(5, 2); + EXPECT_NE(vec.size(), 2); + EXPECT_EQ(vec.start_index(), 2); + +} +TEST(TVectorTest, Destryctor) { + TVector vec; +} +TEST(TVectorTest, PrintVector) { + TVector vec(5, 3); + vec.print(); +} +TEST(TVectorTest, algorithmEmpty) { + TVector vec; + EXPECT_TRUE(vec.empty()); +} +TEST(TVectorTest, algorithmFull) { + TVector vec(5, 0); + EXPECT_FALSE(vec.full()); + + vec.resize(5); + EXPECT_TRUE(vec.full()); +} +TEST(TVectorTest, algorithmSize) { + TVector vec(5, 0); + EXPECT_EQ(vec.size(), 0); + vec.push_back(1); + EXPECT_EQ(vec.size(), 1); + vec.push_back(2); + EXPECT_EQ(vec.size(), 2); +} +TEST(TVectorTest, algorithmStart_index) { + TVector vec(5, 0); + EXPECT_EQ(vec.start_index(), 0); + vec.push_back(1); + EXPECT_EQ(vec.start_index(), 0); + vec.push_back(2); + EXPECT_EQ(vec.start_index(), 0); +} +TEST(TVectorTest, algorithmData) { + TVector vec(5, 0); + EXPECT_NE(vec.data(), nullptr); + vec.push_back(1); + EXPECT_NE(vec.data(), nullptr); + vec.push_back(2); + EXPECT_NE(vec.data(), nullptr); +} +TEST(TVectorTest, algorithmSwap) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + EXPECT_EQ(vec.size(), 2); + + TVector vec2(4, 0); + vec2.push_back(3); + vec2.push_back(4); + EXPECT_EQ(vec2.size(), 2); + + vec.swap(vec2); + + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[0], 3); + EXPECT_EQ(vec[1], 4); + EXPECT_EQ(vec2.size(), 2); + EXPECT_EQ(vec2[0], 1); + EXPECT_EQ(vec2[1], 2); +} +TEST(TVectorTest, algorithmAssign) { + TVector vec(5, 1); + EXPECT_EQ(vec.start_index(), 1); + TVector vec2(4, 0); + EXPECT_EQ(vec2.start_index(), 0); + vec.assign(vec2); + EXPECT_EQ(vec.start_index(), 0); + +} +TEST(TVectorTest, algorithmClear) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + vec.push_back(4); + vec.push_back(5); + EXPECT_EQ(vec.size(), 5); + vec.clear(); + EXPECT_EQ(vec.size(), 0); +} +TEST(TVectorTest, algorithmResize) { + TVector vec(5, 0); + EXPECT_EQ(vec.size(), 0); + vec.resize(5); + EXPECT_EQ(vec.size(), 5); +} +TEST(TVectorTest, algorithmPushBack) { + TVector vec(5, 0); + vec.push_back(2); + EXPECT_EQ(vec[0], 2); + EXPECT_EQ(vec.size(), 1); +} +TEST(TVectorTest, algorithmPopBack) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 3); + vec.pop_back(); + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[1], 2); +} +TEST(TVectorTest, algorithmPushFront) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 3); + vec.push_front(0); + EXPECT_EQ(vec.size(), 4); + EXPECT_EQ(vec[0], 0); +} +TEST(TVectorTest, algorithmPopFront) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 3); + vec.pop_front(); + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[0], 2); +} +TEST(TVectorTest, algorithmInsert1) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 3); + vec.insert(4, 3); + EXPECT_EQ(vec.size(), 4); + EXPECT_EQ(vec[3], 4); +} +TEST(TVectorTest, algorithmReplace) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 3); + vec.replace(2, 5); + EXPECT_EQ(vec.size(), 3); + EXPECT_EQ(vec[2], 5); +} +TEST(TVectorTest, algorithmErase) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 3); + vec.erase(2, 1); + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[1], 2); +} +TEST(TVectorTest, algorithmRemoveAll) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 3); + vec.remove_all(2); + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[1], 3); +} +TEST(TVectorTest, algorithmRemoveFirst) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 3); + vec.remove_first(1); + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[0], 2); +} +TEST(TVectorTest, algorithmRemoveLast) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 3); + vec.remove_last(3); + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[1], 2); +} +TEST(TVectorTest, algorithmRemoveByIndex) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 3); + vec.remove_by_index(1); + EXPECT_EQ(vec.size(), 2); + EXPECT_EQ(vec[1], 3); +} +TEST(TVectorTest, algorithmFindAll) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 4); + + size_t* vec2 = vec.find_all(2); + EXPECT_NE(vec2, nullptr); + + EXPECT_EQ(vec2[0], 2); + EXPECT_EQ(vec2[1], 1); + EXPECT_EQ(vec2[2], 2); +} +TEST(TVectorTest, algorithmFindFirst) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 4); + vec.find_first(2); + EXPECT_EQ(vec[0], 1); +} +TEST(TVectorTest, algorithmFindLast) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(2); + vec.push_back(3); + EXPECT_EQ(vec.size(), 4); + size_t vec2 = vec.find_last(2); + EXPECT_EQ(vec[vec2], 2); +} +TEST(TVectorTest, operatorIndexNonConst) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + + EXPECT_EQ(vec[0], 1); + EXPECT_EQ(vec[1], 2); + EXPECT_EQ(vec[2], 3); + + vec[1] = 4; + EXPECT_EQ(vec[1], 4); +} + +TEST(TVectorTest, operatorIndexConst) { + + TVector vec(3, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + + const TVector const_vec = vec; + EXPECT_EQ(const_vec[0], 1); + EXPECT_EQ(const_vec[1], 2); + EXPECT_EQ(const_vec[2], 3); +} +TEST(TVectorTest, operatorEqually) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + TVector vec2(5, 0); + vec = vec2; + EXPECT_EQ(vec, vec2); +} +TEST(TVectorTest, operatorPlus) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + TVector vec2(5, 0); + vec2.push_back(4); + vec2.push_back(5); + vec2.push_back(6); + TVector vec3 = vec + vec2; + EXPECT_EQ(vec3.size(), 3); + EXPECT_EQ(vec3[0], 5); + EXPECT_EQ(vec3[1], 7); + EXPECT_EQ(vec3[2], 9); +} +TEST(TVectorTest, operatorMinus) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + TVector vec2(5, 0); + vec2.push_back(4); + vec2.push_back(5); + vec2.push_back(6); + TVector vec3 = vec2 - vec; + EXPECT_EQ(vec3.size(), 3); + EXPECT_EQ(vec3[0], 3); + EXPECT_EQ(vec3[1], 3); + EXPECT_EQ(vec3[2], 3); +} +TEST(TVectorTest, operatorMinusQually) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + TVector vec2(5, 0); + vec2.push_back(4); + vec2.push_back(5); + vec2.push_back(6); + + vec2 -= vec; + EXPECT_EQ(vec.size(), 3); + EXPECT_EQ(vec2[0], 3); + EXPECT_EQ(vec2[1], 3); + EXPECT_EQ(vec2[2], 3); +} +TEST(TVectorTest, OperatorPlusQually) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + TVector vec2(5, 0); + vec2.push_back(4); + vec2.push_back(5); + vec2.push_back(6); + vec += vec2; + EXPECT_EQ(vec.size(), 3); + EXPECT_EQ(vec[0], 5); + EXPECT_EQ(vec[1], 7); + EXPECT_EQ(vec[2], 9); +} +TEST(TVectorTest, OperatorMultiplicationQually) { + TVector vec(5, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + + vec *= 3; + EXPECT_EQ(vec.size(), 3); + EXPECT_EQ(vec[0], 3); + EXPECT_EQ(vec[1], 6); + EXPECT_EQ(vec[2], 9); + + +} +TEST(TVectorTest, OperatorMultiplicationQually1) { + TVector vec(10); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + TVector vec2(10); + vec2.push_back(4); + vec2.push_back(5); + vec2.push_back(6); + vec *= vec2; + EXPECT_EQ(vec.size(), 6); + EXPECT_EQ(vec[0], 1); + EXPECT_EQ(vec[1], 2); + EXPECT_EQ(vec[2], 3); + EXPECT_EQ(vec[3], 4); + EXPECT_EQ(vec[4], 5); + EXPECT_EQ(vec[5], 6); + +} + +TEST(TVectorTest, OperatorEquality) { + TVector vec1(3, 0); + vec1.push_back(1); + vec1.push_back(2); + vec1.push_back(3); + + TVector vec2(3, 0); + vec2.push_back(1); + vec2.push_back(2); + vec2.push_back(3); + + EXPECT_TRUE(vec1 == vec2); + + TVector vec3(3, 0); + vec3.push_back(1); + vec3.push_back(2); + vec3.push_back(4); + + EXPECT_FALSE(vec1 == vec3); +} + +TEST(TVectorTest, OperatorInequality) { + TVector vec1(3, 0); + vec1.push_back(1); + vec1.push_back(2); + vec1.push_back(3); + + TVector vec2(3, 0); + vec2.push_back(1); + vec2.push_back(2); + vec2.push_back(3); + + EXPECT_FALSE(vec1 != vec2); + + TVector vec3(3, 0); + vec3.push_back(1); + vec3.push_back(2); + vec3.push_back(4); + + EXPECT_TRUE(vec1 != vec3); +} + +TEST(TVectorTest, OperatorMultiplicationScalar) { + TVector vec(3, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + + TVector result = vec * 2; + + EXPECT_EQ(result.size(), 3); + EXPECT_EQ(result[0], 2); + EXPECT_EQ(result[1], 4); + EXPECT_EQ(result[2], 6); +} + +TEST(TVectorTest, OperatorMultiplicationScalarReverse) { + TVector vec(3, 0); + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + + TVector result = 2 * vec; + + EXPECT_EQ(result.size(), 3); + EXPECT_EQ(result[0], 2); + EXPECT_EQ(result[1], 4); + EXPECT_EQ(result[2], 6); +}