diff --git a/CMakeLists.txt b/CMakeLists.txt index fb5abf3a..4b0ab672 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,13 @@ include(cmake/function.cmake) # подхватываем функции, # для простоты мы объединили наборы команд для создания статической библиотеки # и для создания исполняемого проекта в отдельные функции -add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_easy_example) +add_subdirectory(lib_queue) +add_subdirectory(lib_stack) +add_subdirectory(lib_algorithms) +add_subdirectory(lib_list) +add_subdirectory(lib_doubly_linked_list) +add_subdirectory(lib_tvector) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main diff --git a/lib_DSU/CMakeLists.txt b/lib_DSU/CMakeLists.txt new file mode 100644 index 00000000..424d2417 --- /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 00000000..df47e50b --- /dev/null +++ b/lib_DSU/DSU.cpp @@ -0,0 +1,48 @@ +#include "DSU.h" +#include + +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] = 0; + } +} + +DSU::~DSU() { + delete[] _parent; + delete[] _rank; +} + +int DSU::find(int x) { + if (_parent[x] != x) { + _parent[x] = find(_parent[x]); + } + return _parent[x]; +} + +void DSU::unionSets(int x, int y) { + if (x == y) { + return; + } + int rank_x = find(x); + int rank_y = find(y); + if (rank_x == rank_y) { + return; + } + if (_rank[rank_x] < _rank[rank_y]) { + _parent[rank_x] = rank_y; + } + else if (_rank[rank_x] > _rank[rank_y]) { + _parent[rank_y] = rank_x; + } + else { + _parent[rank_y] = rank_x; + _rank[rank_x]++; + } +} + +int DSU::rank(int x) const { + return _rank[x]; +} \ No newline at end of file diff --git a/lib_DSU/DSU.h b/lib_DSU/DSU.h new file mode 100644 index 00000000..a69c6365 --- /dev/null +++ b/lib_DSU/DSU.h @@ -0,0 +1,22 @@ +#ifndef dsuh +#define dsuh + +class DSU { +private: + int* _parent; + int* _rank; + int _size; + +public: + DSU(int size); + + ~DSU(); + + int find(int x); + + void unionSets(int x, int y); + + int rank(int x) const; +}; + +#endif diff --git a/lib_algorithms/CMakeLists.txt b/lib_algorithms/CMakeLists.txt new file mode 100644 index 00000000..cbdb9b66 --- /dev/null +++ b/lib_algorithms/CMakeLists.txt @@ -0,0 +1,2 @@ +create_project_lib(Algorithms) +add_depend(Algorithms Stack ..\\lib_stack) diff --git a/lib_algorithms/algorithms.cpp b/lib_algorithms/algorithms.cpp new file mode 100644 index 00000000..ea78f634 --- /dev/null +++ b/lib_algorithms/algorithms.cpp @@ -0,0 +1,36 @@ +#include +#include "algorithms.h" +#include + +using std::string; + +bool check_breckets(std::string str) { + std::stack stack; + + if (str.empty()) { + return true; + } + + for (char c : str) { + if (c == '(' || c == '[' || c == '{') { + stack.push(c); + } + else if (c == ')' || c == ']' || c == '}') { + if (stack.empty()) { + return false; + } + + if ((c == ')' && stack.top() != '(') || + (c == ']' && stack.top() != '[') || + (c == '}' && stack.top() != '{')) { + return false; + } + stack.pop(); + } + else { + return false; + } + } + + return stack.empty(); +} \ No newline at end of file diff --git a/lib_algorithms/algorithms.h b/lib_algorithms/algorithms.h new file mode 100644 index 00000000..632c0e02 --- /dev/null +++ b/lib_algorithms/algorithms.h @@ -0,0 +1,7 @@ +#ifndef ALGORITHMS +#define ALGORITHMS +#include + +bool check_breckets(std::string); + +#endif \ No newline at end of file diff --git a/lib_doubly_linked_list/CMakeLists.txt b/lib_doubly_linked_list/CMakeLists.txt new file mode 100644 index 00000000..06b20a7d --- /dev/null +++ b/lib_doubly_linked_list/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(Doubly_linked_list) \ No newline at end of file diff --git a/lib_doubly_linked_list/doubly_linked_list.cpp b/lib_doubly_linked_list/doubly_linked_list.cpp new file mode 100644 index 00000000..e69de29b diff --git a/lib_doubly_linked_list/doubly_linked_list.h b/lib_doubly_linked_list/doubly_linked_list.h new file mode 100644 index 00000000..e69de29b diff --git a/lib_list/CMakeLists.txt b/lib_list/CMakeLists.txt new file mode 100644 index 00000000..148b539a --- /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 00000000..811c5120 --- /dev/null +++ b/lib_list/list.cpp @@ -0,0 +1 @@ +#include "list.h" \ No newline at end of file diff --git a/lib_list/list.h b/lib_list/list.h new file mode 100644 index 00000000..63551463 --- /dev/null +++ b/lib_list/list.h @@ -0,0 +1,311 @@ +#ifndef LIST +#define LIST + +template +struct Node { + T value; + Node* next; + Node(T val, Node* next = nullptr); +}; + +template +class List { + Node* _head, * _tail; + int _count; +public: + List(): _head(nullptr), _tail(nullptr), _count(0) {} + List(const List& other); + List& operator=(const List& other); + ~List(); + + void push_front(const T& val) noexcept; + void push_back(const T& val) noexcept; + void insert(int pos, const T& val); + void insert(Node* node, const T& val); + void pop_front() noexcept; + void pop_back() noexcept; + void erase(int pos); + void erase(Node* node); + bool isEmpty(); + Node* find(const T& val); + + T& front(); + T& back(); + int size() const; + void clear(); + + + + class Iterator { + Node* current; + public: + Iterator(): current(nullptr){} + Iterator(Node* pos) : current(pos) {} + Iterator(const Iterator& other) : current(other.current) {} + + Iterator& operator=(const Iterator& other) { + if (this != &other) { + current = other.current; + } + return *this; + } + + T& operator*() { + if (current == nullptr) { + throw std::runtime_error("Null iterator"); + } + return current->value; + } + + bool operator==(const Iterator& other) const { + return current == other.current; + } + + bool operator!=(const Iterator& other) const { + return current != other.current; + } + + Iterator operator++(int) { + Iterator tmp(*this); + current = current->next; + return tmp; + } + + Iterator& operator++() { + current = current->next; + return *this; + } + }; + + Iterator begin() { + return Iterator(_head); + } + + Iterator end() { + return Iterator(); + } + typedef Iterator iterator; +}; +template +Node::Node(T val, Node* next) : value(val), next(next) {} + +template +List::List(const List& other) : _head(nullptr), _tail(nullptr), _count(0) { + Node* current = other._head; + while (current != nullptr) { + push_back(current->value); + current = current->next; + } +} + +template +List& List::operator=(const List& other) { + if (this != &other) { + clear(); + Node* current = other._head; + while (current != nullptr) { + push_back(current->value); + current = current->next; + } + } + return *this; +} + +template +List::~List() { + clear(); +} + +template +void List::push_front(const T& val) noexcept { + _head = new Node(val, _head); + if (_tail == nullptr) { + _tail = _head; + } + _count++; +} + +template +void List::push_back(const T& val) noexcept { + Node* new_node = new Node(val); + if (_tail == nullptr) { + _head = _tail = new_node; + } + else { + _tail->next = new_node; + _tail = new_node; + } + _count++; +} + +template +void List::insert(int pos, const T& val) { + if (pos < 0 || pos > _count) { + throw std::out_of_range("Position out of range"); + } + + if (pos == 0) { + push_front(val); + } + else if (pos == _count) { + push_back(val); + } + else { + Node* current = _head; + for (int i = 0; i < pos - 1; i++) { + current = current->next; + } + current->next = new Node(val, current->next); + _count++; + } +} + +template +void List::insert(Node* node, const T& val) { + if (node == nullptr) { + push_front(val); + } + else { + Node* new_node = new Node(val, node->next); + node->next = new_node; + if (node == _tail) { + _tail = new_node; + } + _count++; + } +} + +template +void List::pop_front() noexcept { + if (_head == nullptr) return; + + Node* temp = _head; + _head = _head->next; + delete temp; + _count--; + + if (_head == nullptr) { + _tail = nullptr; + } +} + +template +void List::pop_back() noexcept { + if (_tail == nullptr) return; + + if (_head == _tail) { + delete _head; + _head = _tail = nullptr; + } + else { + Node* current = _head; + while (current->next != _tail) { + current = current->next; + } + delete _tail; + _tail = current; + _tail->next = nullptr; + } + _count--; +} + +template +void List::erase(int pos) { + if (pos < 0 || pos >= _count) { + throw std::out_of_range("Position out of range"); + } + + if (pos == 0) { + pop_front(); + } + else { + Node* current = _head; + for (int i = 0; i < pos - 1; i++) { + current = current->next; + } + Node* to_delete = current->next; + current->next = to_delete->next; + + if (to_delete == _tail) { + _tail = current; + } + + delete to_delete; + _count--; + } +} + +template +void List::erase(Node* node) { + if (node == nullptr || _head == nullptr) return; + + if (node == _head) { + pop_front(); + } + else { + Node* current = _head; + while (current->next != node && current->next != nullptr) { + current = current->next; + } + + if (current->next == node) { + current->next = node->next; + if (node == _tail) { + _tail = current; + } + delete node; + _count--; + } + } +} + +template +bool List::isEmpty() { + return _head == nullptr; +} + +template +Node* List::find(const T& val) { + Node* current = _head; + while (current != nullptr) { + if (current->value == val) { + return current; + } + current = current->next; + } + return nullptr; +} + +template +T& List::front() { + if (_head == nullptr) { + throw std::runtime_error("List is empty"); + } + return _head->value; +} + +template +T& List::back() { + if (_tail == nullptr) { + throw std::runtime_error("List is empty"); + } + return _tail->value; +} + +template +int List::size() const { + return _count; +} + +template +void List::clear() { + while (_head != nullptr) { + Node* temp = _head; + _head = _head->next; + delete temp; + } + _tail = nullptr; + _count = 0; +} + +#endif \ No newline at end of file diff --git a/lib_queue/CMakeLists.txt b/lib_queue/CMakeLists.txt new file mode 100644 index 00000000..f0846b24 --- /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 00000000..e69de29b diff --git a/lib_queue/queue.h b/lib_queue/queue.h new file mode 100644 index 00000000..30c9b49b --- /dev/null +++ b/lib_queue/queue.h @@ -0,0 +1,51 @@ +#ifndef QUEUE +#define QUEUE + +#include + +template +class Queue { + T* _data; + int _size; + int _head; + int _count; + +public: + Queue(int size = 20) : _size(size), _head(0), _count(0) { + _data = new T[size]; + } + + ~Queue() { + delete[] _data; + } + + void pop() { + if (isEmpty()) { + throw std::logic_error("Queue is empty"); + } + _count--; + _head = (++_head) % _size; + } + + void push(const T& value) { + if (_count >= _size) { + throw std::logic_error("Queue is full"); + } + int tail = (_head + _count) % _size; + _data[tail] = value; + _count++; + } + + T& front() { + if (isEmpty()) { + throw std::logic_error("Queue is empty"); + } + return _data[_head]; + } + + bool isEmpty() const { + return _count == 0; + } +}; + +#endif \ No newline at end of file diff --git a/lib_stack/CMakeLists.txt b/lib_stack/CMakeLists.txt new file mode 100644 index 00000000..b6bedb01 --- /dev/null +++ b/lib_stack/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(Stack) \ No newline at end of file diff --git a/lib_stack/stack.cpp b/lib_stack/stack.cpp new file mode 100644 index 00000000..e69de29b diff --git a/lib_stack/stack.h b/lib_stack/stack.h new file mode 100644 index 00000000..bb13cc42 --- /dev/null +++ b/lib_stack/stack.h @@ -0,0 +1,66 @@ +#ifndef STACK +#define STACK + +#include + +template +class Stack { + T* _data; + int _size; + int _top; + +public: + Stack(int size = 20) : _size(size), _top(-1) { + _data = new T[size]; + } + + ~Stack() { + delete[] _data; + } + + void push(const T& value) { + if (isFull()) { + throw std::logic_error("Stack is full"); + } + _data[++_top] = value; + } + + void pop() { + if (isEmpty()) { + throw std::logic_error("Stack is empty"); + } + _top--; + } + + T& top() { + if (isEmpty()) { + throw std::logic_error("Stack is empty"); + } + return _data[_top]; + } + + const T& top() const { + if (isEmpty()) { + throw std::logic_error("Stack is empty"); + } + return _data[_top]; + } + + bool isEmpty() const { + return _top == -1; + } + + bool isFull() const { + return _top == _size - 1; + } + + void clear() { + _top = -1; + } + + int size() const { + return _top + 1; + } +}; + +#endif \ No newline at end of file diff --git a/lib_tvector/CMakeLists.txt b/lib_tvector/CMakeLists.txt new file mode 100644 index 00000000..a46980e1 --- /dev/null +++ b/lib_tvector/CMakeLists.txt @@ -0,0 +1 @@ +create_project_lib(TVector) \ No newline at end of file diff --git a/lib_tvector/tvector.cpp b/lib_tvector/tvector.cpp new file mode 100644 index 00000000..f1e4ad6d --- /dev/null +++ b/lib_tvector/tvector.cpp @@ -0,0 +1 @@ +#include "TVector.h" \ No newline at end of file diff --git a/lib_tvector/tvector.h b/lib_tvector/tvector.h new file mode 100644 index 00000000..3aeb9d35 --- /dev/null +++ b/lib_tvector/tvector.h @@ -0,0 +1,395 @@ +#ifndef VECTOR +#define VECTOR +#include + +#define STEP_OF_CAPACITY 15 + +int calc_capacity(int size) { + return (size + STEP_OF_CAPACITY) / STEP_OF_CAPACITY * STEP_OF_CAPACITY; +} + +template class TVector; + +template +std::ostream& operator<<(std::ostream& out, const TVector& vec); + +template class TVector; + +template +std::istream& operator>>(std::istream& in, TVector& vec); + + +template +class TVector { +protected: + + T* _data; + + int _size; + + int _capacity; + +public: + class Iterator { + private: + T* current; + + public: + Iterator() : current(nullptr) {} + Iterator(T* pos) : current(pos) {} + Iterator(const Iterator& other) : current(other.current) {} + + Iterator& operator=(const Iterator& other) { + if (this != &other) { + current = other.current; + } + return *this; + } + + T& operator*() { + if (current == nullptr) { + throw std::runtime_error("Dereferencing null iterator"); + } + return *current; + } + + bool operator==(const Iterator& other) const { + return current == other.current; + } + + bool operator!=(const Iterator& other) const { + return current != other.current; + } + + Iterator& operator++() { + if (current != nullptr) { + current++; + } + return *this; + } + + Iterator operator++(int) { + Iterator tmp = *this; + ++(*this); + return tmp; + } + + Iterator& operator--() { + if (current != nullptr) { + current--; + } + return *this; + } + + Iterator operator--(int) { + Iterator tmp = *this; + --(*this); + return tmp; + } + }; + + typedef Iterator iterator; + + TVector(); + + TVector(const TVector& other); + + TVector(std::initializer_list data); + + TVector(int size); + + TVector(T* data, int size); + + ~TVector(); + + inline T* data() const noexcept; + + inline int size() const noexcept; + + inline int capacity() const noexcept; + + inline T& operator[](int insx) noexcept; + + inline const T& operator[](int indx) const noexcept; + + friend std::ostream& operator<< (std::ostream& out, const TVector& vec); + + friend std::istream& operator>> (std::istream& in, TVector& vec); + + void clear(); + + TVector& operator=(const TVector& other) noexcept; + + int find(T Val) const; + + bool full() const noexcept; + + void reset_memory(); + + void push_front(T number); + + void push_back(T number); + + void insert(int pos, T number); + + void erase(int pos, int count = 1); + + T& front() noexcept; + + T& back() noexcept; + + const T& front() const noexcept; + + const T& back() const noexcept; + + T pop_back(); + + T pop_front(); + + iterator begin() { + return iterator(_data); + } + + iterator end() { + return iterator(_data + _size); + } +}; + +template +TVector::TVector() :_data(nullptr), _size(0), _capacity(0) {} + +template +TVector::TVector(const TVector& other) : _size(other._size), _capacity(calc_capacity(other._size)) { + _data = new T[_capacity]; + for (int i = 0; i < _size; i++) { + _data[i] = other._data[i]; + } +}; + +template +TVector::TVector(std::initializer_list data) { + _size = data.size(); + _capacity = calc_capacity(_size); + _data = new T[_capacity]; + for (int i = 0; i < _size; i++) { + _data[i] = *(data.begin() + i); + } +} + +template +TVector::TVector(int size) { + if (size >= 0) { + _size = size; + _capacity = calc_capacity(size); + _data = new T[_capacity]; + } + else { + throw std::logic_error("size < 0"); + } +} + +template +TVector::TVector(T* data, int size) : _size(size), _capacity(calc_capacity(size)) { + _data = new T[_capacity]; + for (int i = 0; i < _size; ++i) { + _data[i] = data[i]; + } +} + +template +TVector::~TVector() { + clear(); + _size = 0; + _capacity = 0; +} + +template +inline T* TVector::data() const noexcept { + return _data; +} + +template +inline int TVector::size() const noexcept { + return _size; +} + +template +inline int TVector::capacity() const noexcept { + return _capacity; +} + +template +inline T& TVector::operator[](int indx) noexcept { + return _data[indx]; +} + +template +inline const T& TVector::operator[](int indx) const noexcept { + return _data[indx]; +} + +template +std::ostream& operator<<(std::ostream& out, const TVector& vec) { + for (int i = 0; i < vec.size(); i++) { + out << vec[i] << " "; + } + return out; +} + +template +std::istream& operator>>(std::istream& in, TVector& vec) { + vec.clear(); + + T value; + while (in >> value) { + vec.push_back(value); + } + + in.clear(); + return in; +} + +template +void TVector::clear() { + if (_data != nullptr) { + delete[] _data; + _data = nullptr; + } +} + +template +TVector& TVector::operator=(const TVector& other) noexcept { + if (this == &other) { + return *this; + } + if (_data != nullptr) { + delete[] _data; + } + _size = other._size; + _capacity = other._capacity; + _data = new T[_capacity]; + for (int i = 0; i < _size; i++) { + _data[i] = other._data[i]; + } + return *this; +} + +template +int TVector::find(T Number) const { + for (int i = 0; i < _size; i++) + { + if (_data[i] == Number) + return i; + } + throw std::runtime_error("Number not found"); +} + +template +bool TVector::full() const noexcept { + if (_size == _capacity) { + return true; + } + return false; +} + +template +void TVector::reset_memory() { + _capacity = calc_capacity(_size); + T* data = new T[_capacity]; + for (int i = 0; i < _size; i++) + { + data[i] = _data[i]; + } + delete[] _data; + _data = data; +} + +template +void TVector::push_front(T number) { + if (full()) + { + reset_memory(); + } + for (int i = _size; i > 0; i--) + _data[i] = _data[i - 1]; + _data[0] = number; + _size++; +} + +template +void TVector::push_back(T number) { + if (!full()) + _data[_size] = number; + else { + reset_memory(); + _data[_size] = number; + } + _size++; +} + +template +void TVector::insert(int pos, T number) { + if (pos <= _size && pos >= 0) { + if (full()) { + reset_memory(); + } + + for (int i = _size; i > pos; i--) + _data[i] = _data[i - 1]; + _data[pos] = number; + _size++; + } + else + throw std::logic_error("Error in insert: position out of range"); +} + +template +void TVector::erase(int pos, int count) { + if (pos + count > _size || pos < 0 || count <= 0) { + throw std::logic_error("Error in erase: position or count out of range"); + } + for (int i = pos; i < _size - count; i++) { + _data[i] = _data[i + count]; + } + _size -= count; + reset_memory(); +} + +template +T& TVector::front() noexcept { + return _data[0]; +} + +template +T& TVector::back() noexcept { + return _data[_size - 1]; +} + +template +const T& TVector::front() const noexcept { + return _data[0]; +} + +template +const T& TVector::back() const noexcept { + return _data[_size - 1]; +} + +template +T TVector::pop_back() { + T pop = _data[_size - 1]; + _size--; + reset_memory(); + return pop; +} + +template +T TVector::pop_front() { + T pop = _data[0]; + for (int i = 0; i < _size - 1; i++) + _data[i] = _data[i + 1]; + --_size; + reset_memory(); + return pop; +} +#endif \ No newline at end of file diff --git a/tests/test_DSU.cpp b/tests/test_DSU.cpp new file mode 100644 index 00000000..6f6c2220 --- /dev/null +++ b/tests/test_DSU.cpp @@ -0,0 +1,46 @@ +#include +#include "../lib_DSU/DSU.h" + +TEST(DSUTest, Find) { + DSU dsu(5); + + for (int i = 0; i < 5; i++) { + EXPECT_EQ(dsu.find(i), i); + } +} + +TEST(DSUTest, FindMultipleCalls) { + DSU dsu(3); + + EXPECT_EQ(dsu.find(0), 0); + EXPECT_EQ(dsu.find(0), 0); + EXPECT_EQ(dsu.find(1), 1); + EXPECT_EQ(dsu.find(2), 2); + EXPECT_EQ(dsu.find(1), 1); +} + +TEST(DSUTest, SelfUnionDoesNothing) { + DSU dsu(3); + dsu.unionSets(1, 1); + + EXPECT_EQ(dsu.find(0), 0); + EXPECT_EQ(dsu.find(1), 1); + EXPECT_EQ(dsu.find(2), 2); +} + +TEST(DSUTest, RankDependsOnUnionOrder) { + DSU dsu1(4); + DSU dsu2(4); + + dsu1.unionSets(0, 1); + dsu1.unionSets(2, 3); + dsu1.unionSets(0, 2); + + dsu2.unionSets(0, 1); + dsu2.unionSets(1, 2); + dsu2.unionSets(2, 3); + + EXPECT_NE(dsu1.rank(0), dsu2.rank(0)); + + EXPECT_GT(dsu1.rank(0), dsu2.rank(0)); +} \ No newline at end of file diff --git a/tests/tests_algorithms.cpp b/tests/tests_algorithms.cpp new file mode 100644 index 00000000..27d7cf0d --- /dev/null +++ b/tests/tests_algorithms.cpp @@ -0,0 +1,52 @@ +#include +#include "../lib_algorithms/algorithms.h" + + +TEST(CheckBracketsTest, empty_string) { + EXPECT_TRUE(check_breckets("")); +} + +TEST(CheckBracketsTest, simple_correct_pairs) { + EXPECT_TRUE(check_breckets("()")); + EXPECT_TRUE(check_breckets("[]")); + EXPECT_TRUE(check_breckets("{}")); +} + +TEST(CheckBracketsTest, nested_correct) { + EXPECT_TRUE(check_breckets("({[]})")); + EXPECT_TRUE(check_breckets("()[]{}")); + EXPECT_TRUE(check_breckets("{[()]}")); +} + +TEST(CheckBracketsTest, unmatched_opening) { + EXPECT_FALSE(check_breckets("(")); + EXPECT_FALSE(check_breckets("[")); + EXPECT_FALSE(check_breckets("{")); + EXPECT_FALSE(check_breckets("({")); +} + +TEST(CheckBracketsTest, unmatched_closing) { + EXPECT_FALSE(check_breckets(")")); + EXPECT_FALSE(check_breckets("]")); + EXPECT_FALSE(check_breckets("}")); + EXPECT_FALSE(check_breckets("())")); +} + +TEST(CheckBracketsTest, wrong_order) { + EXPECT_FALSE(check_breckets("([)]")); + EXPECT_FALSE(check_breckets("{(})")); + EXPECT_FALSE(check_breckets("][")); +} + +TEST(CheckBracketsTest, wrong_pairs) { + EXPECT_FALSE(check_breckets("(]")); + EXPECT_FALSE(check_breckets("{)")); + EXPECT_FALSE(check_breckets("[}")); +} + +TEST(CheckBracketsTest, invalid_characters) { + EXPECT_FALSE(check_breckets("a")); + EXPECT_FALSE(check_breckets("(a)")); + EXPECT_FALSE(check_breckets("1")); + EXPECT_FALSE(check_breckets("()a")); +} \ No newline at end of file diff --git a/tests/tests_doubly_linked_list.cpp b/tests/tests_doubly_linked_list.cpp new file mode 100644 index 00000000..e69de29b diff --git a/tests/tests_list.cpp b/tests/tests_list.cpp new file mode 100644 index 00000000..27696891 --- /dev/null +++ b/tests/tests_list.cpp @@ -0,0 +1,323 @@ +#include +#include "../lib_list/list.h" + +TEST(ListTest, create_list) { + ASSERT_NO_THROW(List list); +} + +TEST(ListTest, push_front_and_pop_front) { + List list; + list.push_front(10); + list.push_front(20); + + EXPECT_EQ(list.front(), 20); + list.pop_front(); + EXPECT_EQ(list.front(), 10); +} + +TEST(ListTest, push_back_and_pop_back) { + List list; + list.push_back(10); + list.push_back(20); + + EXPECT_EQ(list.back(), 20); + list.pop_back(); + EXPECT_EQ(list.back(), 10); +} + +TEST(ListTest, check_empty) { + List list; + EXPECT_TRUE(list.isEmpty()); + + list.push_front(1); + EXPECT_FALSE(list.isEmpty()); + + list.pop_front(); + EXPECT_TRUE(list.isEmpty()); +} + +TEST(ListTest, throw_when_empty_front) { + List list; + EXPECT_THROW(list.front(), std::runtime_error); +} + +TEST(ListTest, throw_when_empty_back) { + List list; + EXPECT_THROW(list.back(), std::runtime_error); +} + +TEST(ListTest, size_after_operations) { + List list; + EXPECT_EQ(list.size(), 0); + + list.push_front(1); + EXPECT_EQ(list.size(), 1); + + list.push_back(2); + EXPECT_EQ(list.size(), 2); + + list.pop_front(); + EXPECT_EQ(list.size(), 1); + + list.pop_back(); + EXPECT_EQ(list.size(), 0); +} + +TEST(ListTest, find_existing_element) { + List list; + list.push_back(10); + list.push_back(20); + list.push_back(30); + + Node* found = list.find(20); + ASSERT_NE(found, nullptr); + EXPECT_EQ(found->value, 20); +} + +TEST(ListTest, find_non_existing_element) { + List list; + list.push_back(10); + list.push_back(20); + + Node* found = list.find(30); + EXPECT_EQ(found, nullptr); +} + +TEST(ListTest, insert_at_beginning) { + List list; + list.push_back(2); + list.push_back(3); + list.insert(0, 1); + + EXPECT_EQ(list.front(), 1); + EXPECT_EQ(list.size(), 3); +} + +TEST(ListTest, insert_at_end) { + List list; + list.push_back(1); + list.push_back(2); + list.insert(2, 3); + + EXPECT_EQ(list.back(), 3); + EXPECT_EQ(list.size(), 3); +} + +TEST(ListTest, insert_in_middle) { + List list; + list.push_back(1); + list.push_back(3); + list.insert(1, 2); + + EXPECT_EQ(list.size(), 3); + + EXPECT_EQ(list.front(), 1); + list.pop_front(); + EXPECT_EQ(list.front(), 2); +} + +TEST(ListTest, throw_when_insert_invalid_position) { + List list; + EXPECT_THROW(list.insert(-1, 1), std::out_of_range); + EXPECT_THROW(list.insert(1, 1), std::out_of_range); + + list.push_back(1); + EXPECT_THROW(list.insert(2, 2), std::out_of_range); +} + +TEST(ListTest, erase_from_beginning) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + + list.erase(0); + EXPECT_EQ(list.front(), 2); + EXPECT_EQ(list.size(), 2); +} + +TEST(ListTest, erase_from_end) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + + list.erase(2); + EXPECT_EQ(list.back(), 2); + EXPECT_EQ(list.size(), 2); +} + +TEST(ListTest, erase_from_middle) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + + list.erase(1); + EXPECT_EQ(list.size(), 2); + EXPECT_EQ(list.front(), 1); + EXPECT_EQ(list.back(), 3); +} + +TEST(ListTest, throw_when_erase_invalid_position) { + List list; + EXPECT_THROW(list.erase(-1), std::out_of_range); + EXPECT_THROW(list.erase(0), std::out_of_range); + + list.push_back(1); + EXPECT_THROW(list.erase(1), std::out_of_range); +} + +TEST(ListTest, clear_list) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + + list.clear(); + EXPECT_TRUE(list.isEmpty()); + EXPECT_EQ(list.size(), 0); + EXPECT_THROW(list.front(), std::runtime_error); +} + +TEST(ListTest, copy_constructor) { + List list1; + list1.push_back(1); + list1.push_back(2); + list1.push_back(3); + + List list2(list1); + EXPECT_EQ(list2.size(), 3); + EXPECT_EQ(list2.front(), 1); + EXPECT_EQ(list2.back(), 3); +} + +TEST(ListTest, assignment_operator) { + List list1; + list1.push_back(1); + list1.push_back(2); + + List list2; + list2 = list1; + + EXPECT_EQ(list2.size(), 2); + EXPECT_EQ(list2.front(), 1); + EXPECT_EQ(list2.back(), 2); +} + +TEST(ListTest, pop_front_until_empty) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + + list.pop_front(); + list.pop_front(); + list.pop_front(); + + EXPECT_TRUE(list.isEmpty()); + EXPECT_EQ(list.size(), 0); + EXPECT_NO_THROW(list.pop_front()); +} + +TEST(ListTest, pop_back_until_empty) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + + list.pop_back(); + list.pop_back(); + list.pop_back(); + + EXPECT_TRUE(list.isEmpty()); + EXPECT_EQ(list.size(), 0); + EXPECT_NO_THROW(list.pop_back()); +} + +TEST(ListTest, mixed_operations) { + List list; + + list.push_front(2); + list.push_back(3); + list.push_front(1); + + EXPECT_EQ(list.size(), 3); + EXPECT_EQ(list.front(), 1); + EXPECT_EQ(list.back(), 3); + + list.pop_front(); + list.pop_back(); + + EXPECT_EQ(list.size(), 1); + EXPECT_EQ(list.front(), 2); + EXPECT_EQ(list.back(), 2); + + list.clear(); + EXPECT_TRUE(list.isEmpty()); +} + +TEST(ListTest, string_list) { + List list; + list.push_back("hello"); + list.push_back("world"); + + EXPECT_EQ(list.size(), 2); + EXPECT_EQ(list.front(), "hello"); + EXPECT_EQ(list.back(), "world"); + + list.pop_front(); + EXPECT_EQ(list.front(), "world"); +} + +TEST(ListTest, double_list) { + List list; + list.push_back(3.14); + list.push_back(2.71); + + EXPECT_DOUBLE_EQ(list.front(), 3.14); + EXPECT_DOUBLE_EQ(list.back(), 2.71); +} + +TEST(ListTest, iterator_compare) { + List list; + int expected_val = 1; + + for (int i = 0; i < 10; i++) { + list.push_back(i + 1); + } + + for (List::iterator it = list.begin(); it != list.end(); it++) { + EXPECT_EQ(*it, expected_val); + expected_val++; + } +} + +TEST(ListTest, iterator_insert) { + List list; + + for (int i = 0; i < 10; i++) { + list.push_back(0); + } + + int set_val = 1; + for (List::iterator it = list.begin(); it != list.end(); it++) { + *it = set_val; + set_val++; + } + + int check_val = 1; + for (List::iterator it = list.begin(); it != list.end(); it++) { + EXPECT_EQ(*it, check_val); + check_val++; + } +} + +TEST(ListTest, iterator_create) { + List list; + ASSERT_NO_THROW( + for (List::iterator it = list.begin(); it != list.end(); it++) { + *it = 0; + } + ); +} \ No newline at end of file diff --git a/tests/tests_queue.cpp b/tests/tests_queue.cpp new file mode 100644 index 00000000..dcf1af54 --- /dev/null +++ b/tests/tests_queue.cpp @@ -0,0 +1,58 @@ +#include +#include "../lib_queue/queue.h" + +TEST(QueueTest, create_queue) { + ASSERT_NO_THROW(Queue q(5)); +} + +TEST(QueueTest, push_and_pop) { + Queue q(5); + q.push(10); + q.push(20); + + EXPECT_EQ(q.front(), 10); + q.pop(); + EXPECT_EQ(q.front(), 20); +} + +TEST(QueueTest, check_empty) { + Queue q(3); + EXPECT_TRUE(q.isEmpty()); + + q.push(1); + EXPECT_FALSE(q.isEmpty()); + + q.pop(); + EXPECT_TRUE(q.isEmpty()); +} + +TEST(QueueTest, throw_when_empty) { + Queue q(3); + EXPECT_THROW(q.pop(), std::logic_error); + EXPECT_THROW(q.front(), std::logic_error); +} + +TEST(QueueTest, throw_when_full) { + Queue q(2); + q.push(1); + q.push(2); + + EXPECT_THROW(q.push(3), std::logic_error); +} + +TEST(QueueTest, circular_behavior) { + Queue q(3); + q.push(1); + q.push(2); + q.push(3); + + q.pop(); // _head = 1 + q.pop(); // _head = 2 + + q.push(4); // tail = (2 + 1) % 3 = 0 + q.push(5); // tail = (2 + 2) % 3 = 1 + + EXPECT_EQ(q.front(), 3); + q.pop(); + EXPECT_EQ(q.front(), 4); +} diff --git a/tests/tests_stack.cpp b/tests/tests_stack.cpp new file mode 100644 index 00000000..bf446844 --- /dev/null +++ b/tests/tests_stack.cpp @@ -0,0 +1,91 @@ +#include +#include "../lib_stack/stack.h" + +TEST(StackTest, create_stack) { + ASSERT_NO_THROW(Stack s(5)); +} + +TEST(StackTest, push_and_top) { + Stack s(5); + s.push(10); + s.push(20); + + EXPECT_EQ(s.top(), 20); +} + +TEST(StackTest, push_and_pop) { + Stack s(5); + s.push(10); + s.push(20); + s.push(30); + + EXPECT_EQ(s.top(), 30); + s.pop(); + EXPECT_EQ(s.top(), 20); + s.pop(); + EXPECT_EQ(s.top(), 10); +} + +TEST(StackTest, check_empty) { + Stack s(3); + EXPECT_TRUE(s.isEmpty()); + + s.push(1); + EXPECT_FALSE(s.isEmpty()); + + s.pop(); + EXPECT_TRUE(s.isEmpty()); +} + +TEST(StackTest, check_full) { + Stack s(2); + EXPECT_FALSE(s.isFull()); + + s.push(1); + EXPECT_FALSE(s.isFull()); + + s.push(2); + EXPECT_TRUE(s.isFull()); +} + +TEST(StackTest, throw_when_empty) { + Stack s(3); + EXPECT_THROW(s.pop(), std::logic_error); + EXPECT_THROW(s.top(), std::logic_error); +} + +TEST(StackTest, throw_when_full) { + Stack s(2); + s.push(1); + s.push(2); + + EXPECT_THROW(s.push(3), std::logic_error); +} + +TEST(StackTest, clear_stack) { + Stack s(5); + s.push(1); + s.push(2); + s.push(3); + + EXPECT_FALSE(s.isEmpty()); + s.clear(); + EXPECT_TRUE(s.isEmpty()); +} + +TEST(StackTest, check_size) { + Stack s(5); + EXPECT_EQ(s.size(), 0); + + s.push(1); + EXPECT_EQ(s.size(), 1); + + s.push(2); + EXPECT_EQ(s.size(), 2); + + s.pop(); + EXPECT_EQ(s.size(), 1); + + s.clear(); + EXPECT_EQ(s.size(), 0); +} \ No newline at end of file diff --git a/tests/tests_tvector.cpp b/tests/tests_tvector.cpp new file mode 100644 index 00000000..53a915aa --- /dev/null +++ b/tests/tests_tvector.cpp @@ -0,0 +1,138 @@ +#include +#include "../lib_tvector/tvector.h" + +TEST(TestTVector, no_throw) { + ASSERT_NO_THROW(TVector vec); +} + +TEST(TestTVector, deffault_constructor) { + TVector vec; + + EXPECT_EQ(vec.size(), 0); + EXPECT_EQ(vec.capacity(), 0); + EXPECT_EQ(vec.data(), nullptr); +} + +TEST(TestTVector, create_vector_with_initlist_constructor_and_clear_and_out) { + TVector vec({ 1, 2, 3, 4, 5, 6, 7 }); + + EXPECT_EQ(vec.size(), 7); + EXPECT_EQ(vec.capacity(), 15); + EXPECT_NE(vec.data(), nullptr); + + for (int i = 0; i < vec.size(); i++) { + EXPECT_EQ(vec[i], i + 1); + } + EXPECT_EQ(vec[3], 4); + vec.clear(); + EXPECT_EQ(vec.size(), 7); + EXPECT_EQ(vec.capacity(), 15); + EXPECT_EQ(vec.data(), nullptr); +} + +TEST(TestTVector, constructors_and_copy_test) { + int n = 10; + int* mas = new int[n]; + for (int i = 0; i < n; i++) { + mas[i] = i; + } + TVector vec1(5); + TVector vec2(mas, 7); + vec1 = vec2; + EXPECT_EQ(vec1.size(), 7); + EXPECT_EQ(vec1.capacity(), 15); + EXPECT_NE(vec1.data(), nullptr); + EXPECT_EQ(vec1[3], 3); + EXPECT_EQ(vec1.find(5), 5); +} + +TEST(TestTVector, all_inserts_test) { + int n = 10; + int* mas = new int[n]; + for (int i = 0; i < n; i++) { + mas[i] = i; + } + TVector vec(mas, n); + vec.push_back(11); + EXPECT_EQ(vec[10], 11); + vec.push_front(-1); + EXPECT_EQ(vec[0], -1); + vec.insert(5, 40); + EXPECT_EQ(vec[5], 40); + EXPECT_EQ(vec.front(), -1); + EXPECT_EQ(vec.back(), 11); +} + +TEST(TestTVector, all_pop_test) { + int n = 10; + int* mas = new int[n]; + for (int i = 0; i < n; i++) { + mas[i] = i; + } + TVector vec(mas, n); + vec.pop_back(); + ASSERT_ANY_THROW(vec.find(9)); + EXPECT_EQ(vec.size(), 9); + vec.erase(3); + EXPECT_EQ(vec[3], 4); + EXPECT_EQ(vec.size(), 8); + ASSERT_ANY_THROW(vec.erase(4, 5);); + vec.pop_front(); + EXPECT_EQ(vec[0], 1); +} + +TEST(VectorIteratorTest, empty_vector_iteration) { + TVector vec; + + EXPECT_TRUE(vec.begin() == vec.end()); + + int iteration_count = 0; + for (auto it = vec.begin(); it != vec.end(); ++it) { + iteration_count++; + } + EXPECT_EQ(iteration_count, 0); +} + +TEST(VectorIteratorTest, iterator_write_operations) { + TVector vec; + vec.push_back(1); + vec.push_back(2); + vec.push_back(3); + + int new_value = 10; + for (auto it = vec.begin(); it != vec.end(); ++it) { + *it = new_value; + new_value += 10; + } + + EXPECT_EQ(vec[0], 10); + EXPECT_EQ(vec[1], 20); + EXPECT_EQ(vec[2], 30); + + auto it = vec.begin(); + *it = 100; + EXPECT_EQ(vec[0], 100); + + ++it; + *it = 200; + EXPECT_EQ(vec[1], 200); +} + +TEST(VectorIteratorTest, iterator_read_operations) { + TVector vec; + vec.push_back(5); + vec.push_back(10); + vec.push_back(15); + + auto it = vec.begin(); + EXPECT_EQ(*it, 5); + + ++it; + EXPECT_EQ(*it, 10); + + it++; + EXPECT_EQ(*it, 15); + + ++it; + EXPECT_TRUE(it == vec.end()); +} \ No newline at end of file