diff --git a/CMakeLists.txt b/CMakeLists.txt index fb5abf3a..9de9527b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,8 +13,14 @@ include(cmake/function.cmake) # подхватываем функции, # для простоты мы объединили наборы команд для создания статической библиотеки # и для создания исполняемого проекта в отдельные функции -add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_queue) +add_subdirectory(lib_list) +add_subdirectory(lib_doubly_linked_list) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_stack) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_dsu) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_algorithms) add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main option(BTEST "build test?" ON) # указываем подключаем ли google-тесты (ON или YES) или нет (OFF или NO) 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..e69de29b diff --git a/lib_dsu/dsu.h b/lib_dsu/dsu.h new file mode 100644 index 00000000..ae957591 --- /dev/null +++ b/lib_dsu/dsu.h @@ -0,0 +1,44 @@ +#pragma once +class DSU { + int* _parent; + int* _rank; + int _size; +public: + DSU(int size); + void unite(int, int); + int find(int); + ~DSU(); +}; +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::unite(int x, int y) { + int rootX = find(x); + int rootY = find(y); + if (rootX == rootY) return; + if (_rank[rootX] < _rank[rootY]) { + _parent[rootX] = rootY; + } + else if (_rank[rootX] > _rank[rootY]) { + _parent[rootY] = rootX; + } + else { + _parent[rootY] = rootX; + _rank[rootX]++; + } +} \ No newline at end of file diff --git a/tests/test_algorithms.cpp b/tests/test_algorithms.cpp new file mode 100644 index 00000000..3ef27dd9 --- /dev/null +++ b/tests/test_algorithms.cpp @@ -0,0 +1,35 @@ +#include +#include "algorithms.h" +#include "stack.h" +TEST(AlgorithmsTest, 1) { + EXPECT_TRUE(check_algorithms("()")); + EXPECT_TRUE(check_algorithms("{}")); + EXPECT_TRUE(check_algorithms("[]")); +} + +TEST(AlgorithmsTest, 2) { + EXPECT_TRUE(check_algorithms("({[]})")); + EXPECT_TRUE(check_algorithms("{[()]}")); + EXPECT_TRUE(check_algorithms("({})[]")); +} + +TEST(AlgorithmsTest, 3) { + EXPECT_FALSE(check_algorithms("(")); + EXPECT_FALSE(check_algorithms(")")); + EXPECT_FALSE(check_algorithms("{[}")); + EXPECT_FALSE(check_algorithms("({[}])")); +} +TEST(AlgorithmsTest, 4) { + EXPECT_FALSE(check_algorithms("([)]")); + EXPECT_FALSE(check_algorithms("{(})")); +} +TEST(AlgorithmsTest, 5) { + EXPECT_TRUE(check_algorithms("()[]{}")); + EXPECT_TRUE(check_algorithms("({[]})[]{}")); +} + +TEST(AlgorithmsTest, 6) { + EXPECT_FALSE(check_algorithms("())")); + EXPECT_FALSE(check_algorithms("{[}]")); + EXPECT_FALSE(check_algorithms("(((")); +} \ No newline at end of file diff --git a/tests/test_doubly_linked_list.cpp b/tests/test_doubly_linked_list.cpp new file mode 100644 index 00000000..78d4fb60 --- /dev/null +++ b/tests/test_doubly_linked_list.cpp @@ -0,0 +1,61 @@ +#include +#include "doubly_linked_list.h" +TEST(DoublyLinkedListTest, IteratorEmpty) { + DoublyLinkedList list; + EXPECT_TRUE(list.begin() == list.end()); + EXPECT_EQ(list.size(), 0); + int count = 0; + for (auto it = list.begin(); it != list.end(); ++it) { + count++; + } + EXPECT_EQ(count, 0); + count = 0; + for (auto it = list.end(); it != list.begin(); --it) { + count++; + } + EXPECT_EQ(count, 0); +} +TEST(DoublyLinkedListTest, IteratorWrite) { + DoublyLinkedList list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + int value = 10; + for (auto it = list.begin(); it != list.end(); ++it) { + *it = value; + value += 10; + } + value = 10; + for (auto it = list.begin(); it != list.end(); ++it) { + EXPECT_EQ(*it, value); + value += 10; + } +} +TEST(DoublyLinkedListTest, IteratorReadAndBidirectional) { + DoublyLinkedList list; + + list.push_back(10); + list.push_back(20); + list.push_back(30); + + // + auto it = list.begin(); + EXPECT_EQ(*it, 10); + ++it; + EXPECT_EQ(*it, 20); + ++it; + EXPECT_EQ(*it, 30); + + // ( end()!) + auto it2 = list.begin(); + ++it2; // 20 + --it2; // 10 + EXPECT_EQ(*it2, 10); + + // + int sum = 0; + for (auto it = list.begin(); it != list.end(); ++it) { + sum += *it; + } + EXPECT_EQ(sum, 60); +} \ No newline at end of file diff --git a/tests/test_dsu.cpp b/tests/test_dsu.cpp new file mode 100644 index 00000000..0ee2732a --- /dev/null +++ b/tests/test_dsu.cpp @@ -0,0 +1,47 @@ +#include +#include "dsu.h" +TEST(DSUTest, InitialState) { + DSU dsu(5); + for (int i = 0; i < 5; i++) { + EXPECT_EQ(dsu.find(i), i); + } +} +TEST(DSUTest, SimpleUnion) { + DSU dsu(3); + dsu.unite(0, 1); + EXPECT_EQ(dsu.find(0), dsu.find(1)); + EXPECT_NE(dsu.find(0), dsu.find(2)); +} +TEST(DSUTest, TransitiveUnion) { + DSU dsu(4); + dsu.unite(0, 1); + dsu.unite(1, 2); + EXPECT_EQ(dsu.find(0), dsu.find(2)); + EXPECT_NE(dsu.find(0), dsu.find(3)); +} +TEST(DSUTest, MultipleUnions) { + DSU dsu(6); + dsu.unite(0, 1); + dsu.unite(2, 3); + dsu.unite(4, 5); + EXPECT_EQ(dsu.find(0), dsu.find(1)); + EXPECT_EQ(dsu.find(2), dsu.find(3)); + EXPECT_EQ(dsu.find(4), dsu.find(5)); + EXPECT_NE(dsu.find(0), dsu.find(2)); + EXPECT_NE(dsu.find(0), dsu.find(4)); + EXPECT_NE(dsu.find(2), dsu.find(4)); +} +TEST(DSUTest, UnionAllElements) { + DSU dsu(5); + for (int i = 0; i < 4; i++) { + dsu.unite(i, i + 1); + } + for (int i = 1; i < 5; i++) { + EXPECT_EQ(dsu.find(0), dsu.find(i)); + } +} +TEST(DSUTest, SelfUnion) { + DSU dsu(3); + dsu.unite(0, 0); + EXPECT_EQ(dsu.find(0), 0); +} \ No newline at end of file diff --git a/tests/test_list.cpp b/tests/test_list.cpp new file mode 100644 index 00000000..6a309f7c --- /dev/null +++ b/tests/test_list.cpp @@ -0,0 +1,176 @@ +#include +#include "../lib_list/list.h" +TEST(ListTest, CreateEmpty) { + List list; + EXPECT_TRUE(list.is_empty()); + EXPECT_EQ(list.size(), 0); +} +TEST(ListTest, CopyConstructor) { + List list1; + list1.push_back(1); + list1.push_back(2); + + List list2(list1); + EXPECT_EQ(list2.size(), 2); +} +TEST(ListTest, Assignment) { + List list1; + list1.push_back(10); + list1.push_back(20); + + List list2; + list2 = list1; + EXPECT_EQ(list2.size(), 2); +} + +TEST(ListTest, DestructorWorks) { + List list; + list.push_back(1); + list.push_back(2); +} +TEST(ListTest, PushElements) { + List list; + list.push_front(2); + list.push_back(3); + list.push_front(1); + EXPECT_EQ(list.size(), 3); +} +TEST(ListTest, PopElements) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + list.pop_front(); + list.pop_back(); + EXPECT_EQ(list.size(), 1); +} +TEST(ListTest, InsertErase) { + List list; + list.push_back(1); + list.push_back(3); + list.insert(1, 2); + list.erase(0); + EXPECT_EQ(list.size(), 2); +} +TEST(ListTest, Clear) { + List list; + list.push_back(1); + list.push_back(2); + list.clear(); + EXPECT_TRUE(list.is_empty()); +} +TEST(ListTest, Find) { + List list; + list.push_back(10); + list.push_back(20); + Node* found = list.find(20); + EXPECT_NE(found, nullptr); +} +TEST(ListTest, Exceptions) { + List list; + EXPECT_THROW(list.pop_front(), std::logic_error); + list.push_back(1); + EXPECT_THROW(list.erase(5), std::logic_error); +} +TEST(ListTest, Iterators) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + int sum = 0; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + sum += *it; + } + EXPECT_EQ(sum, 6); +} +TEST(ListTest, DifferentTypes) { + List list; + list.push_back("hello"); + list.push_back("world"); + EXPECT_EQ(list.size(), 2); +} +TEST(ListTest, IteratorRead) { + List list; + for (int i = 0; i < 5; i++) { + list.push_back(i * 2); + } + std::vector result; + for (List::Iterator it = list.begin(); it != list.end(); it++) { + result.push_back(*it); + } + EXPECT_EQ(result.size(), 5u); + EXPECT_EQ(result[0], 0); + EXPECT_EQ(result[1], 2); + EXPECT_EQ(result[2], 4); + EXPECT_EQ(result[3], 6); + EXPECT_EQ(result[4], 8); +} + +TEST(ListTest, IteratorWrite) { + List list; + for (int i = 0; i < 5; i++) { + list.push_back(0); + } + int value = 1; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + *it = value * 10; + value++; + } + value = 1; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + EXPECT_EQ(*it, value * 10); + value++; + } +} + +TEST(ListTest, IteratorEmptyList) { + List list; + List::Iterator it1 = list.begin(); + EXPECT_EQ(it1, list.end()); + EXPECT_TRUE(list.begin() == list.end()); + int count = 0; + for (List::Iterator it = list.begin(); it != list.end(); it++) { + count++; + } + EXPECT_EQ(count, 0); + count = 0; + for (List::Iterator it = list.begin(); it != list.end(); ++it) { + count++; + } + EXPECT_EQ(count, 0); +} +//TEST(ListTest, can_read) { +// Listlist; +// for (int i = 0; i < 10; i++) { +// list.push_back(i + 1); +// } +// int expected_val = 1; +// for (List::Iterator it = list.begin(); it != list.end(); it++) { +// *it = expected_val; +// expected_val++; +// } +// expected_val = 1; +// for (List::Iterator it = list.begin(); it != list.end(); it++) { +// EXPECT_EQ(*it, expected_val); +// expected_val++; +// } +//} +//TEST(ListTest, can_write) { +// Listlist; +// int expected_val = 1; +// for (List::Iterator it = list.begin(); it != list.end(); it++) { +// EXPECT_EQ(*it, expected_val); +// expected_val++; +// } +//} +//TEST(ListTest, is_empty) { +// Listlist; +// for (List::Iterator it = list.begin(); it != list.end(); it++) { +// *it = 0; +// } +//} + + + + + diff --git a/tests/test_queue.cpp b/tests/test_queue.cpp new file mode 100644 index 00000000..4fb53430 --- /dev/null +++ b/tests/test_queue.cpp @@ -0,0 +1,130 @@ +#include +#include "queue.h" +TEST(QueueTest, ConstructorWithSize) { + Queue q(5); + EXPECT_TRUE(q.is_empty()); + EXPECT_EQ(q.size(), 0); +} +TEST(QueueTest, DefaultConstructor) { + Queue q; + EXPECT_TRUE(q.is_empty()); + q.enqueue(1); + EXPECT_FALSE(q.is_empty()); +} +TEST(QueueTest, CopyConstructor) { + Queue q1(3); + q1.enqueue(1); + q1.enqueue(2); + Queue q2(q1); + EXPECT_EQ(q2.size(), 2); + EXPECT_EQ(q2.front(), 1); +} +TEST(QueueTest, AssignmentOperator) { + Queue q1(3); + q1.enqueue(10); + q1.enqueue(20); + Queue q2(2); + q2 = q1; + EXPECT_EQ(q2.size(), 2); + EXPECT_EQ(q2.front(), 10); +} +TEST(QueueTest, EnqueueMethod) { + Queue q(3); + q.enqueue(42); + EXPECT_EQ(q.size(), 1); + EXPECT_EQ(q.front(), 42); +} +TEST(QueueTest, DequeueMethod) { + Queue q(3); + q.enqueue(1); + q.enqueue(2); + q.dequeue(); + EXPECT_EQ(q.size(), 1); + EXPECT_EQ(q.front(), 2); +} +TEST(QueueTest, FrontMethod) { + Queue q(3); + q.enqueue(100); + EXPECT_EQ(q.front(), 100); +} +TEST(QueueTest, BackMethod) { + Queue q(3); + q.enqueue(1); + q.enqueue(2); + EXPECT_EQ(q.back(), 2); +} +TEST(QueueTest, IsEmptyMethod) { + Queue q(3); + EXPECT_TRUE(q.is_empty()); + q.enqueue(1); + EXPECT_FALSE(q.is_empty()); +} +TEST(QueueTest, IsFullMethod) { + Queue q(2); + EXPECT_FALSE(q.is_full()); + q.enqueue(1); + q.enqueue(2); + EXPECT_TRUE(q.is_full()); +} +TEST(QueueTest, SizeMethod) { + Queue q(3); + EXPECT_EQ(q.size(), 0); + q.enqueue(1); + EXPECT_EQ(q.size(), 1); +} +TEST(QueueTest, ClearMethod) { + Queue q(3); + q.enqueue(1); + q.enqueue(2); + q.clear(); + EXPECT_TRUE(q.is_empty()); + EXPECT_EQ(q.size(), 0); +} +TEST(QueueTest, ExceptionEmptyDequeue) { + Queue q(3); + EXPECT_THROW(q.dequeue(), std::logic_error); +} +TEST(QueueTest, ExceptionEmptyFront) { + Queue q(3); + EXPECT_THROW(q.front(), std::logic_error); +} +TEST(QueueTest, ExceptionEmptyBack) { + Queue q(3); + EXPECT_THROW(q.back(), std::logic_error); +} +TEST(QueueTest, ExceptionFullEnqueue) { + Queue q(2); + q.enqueue(1); + q.enqueue(2); + EXPECT_THROW(q.enqueue(3), std::logic_error); +} +TEST(QueueTest, ExceptionInvalidSize) { + EXPECT_THROW(Queue q(0), std::invalid_argument); + EXPECT_THROW(Queue q(-5), std::invalid_argument); +} +TEST(QueueTest, CircularBehavior) { + Queue q(3); + q.enqueue(1); + q.enqueue(2); + q.enqueue(3); + q.dequeue(); + q.enqueue(4); + EXPECT_EQ(q.front(), 2); + EXPECT_EQ(q.back(), 4); +} +TEST(QueueTest, DifferentTypes) { + Queue q1(3); + q1.enqueue(3.14); + EXPECT_DOUBLE_EQ(q1.front(), 3.14); + Queue q2(3); + q2.enqueue("test"); + EXPECT_EQ(q2.front(), "test"); +} +TEST(QueueTest, ReuseAfterClear) { + Queue q(3); + q.enqueue(1); + q.enqueue(2); + q.clear(); + q.enqueue(10); + EXPECT_EQ(q.front(), 10); +} \ No newline at end of file diff --git a/tests/test_stack.cpp b/tests/test_stack.cpp new file mode 100644 index 00000000..a5a9ae71 --- /dev/null +++ b/tests/test_stack.cpp @@ -0,0 +1,132 @@ +#include +#include "../lib_stack/stack.h" +#include +TEST(StackTest, Constructor) { + Stack stack(10); + EXPECT_TRUE(stack.is_empty()); + EXPECT_FALSE(stack.is_full()); +} +TEST(StackTest, CopyConstructor) { + Stack original(5); + original.push(1); + original.push(2); + Stack copy(original); + EXPECT_EQ(copy.top(), 2); + copy.pop(); + EXPECT_EQ(copy.top(), 1); +} +TEST(StackTest, AssignmentOperator) { + Stack stack1(5); + stack1.push(10); + stack1.push(20); + Stack stack2(3); + stack2 = stack1; + EXPECT_EQ(stack2.top(), 20); +} +TEST(StackTest, InvalidSize) { + EXPECT_THROW(Stack stack(0), std::invalid_argument); + EXPECT_THROW(Stack stack(-5), std::invalid_argument); +} +TEST(StackTest, Push) { + Stack stack(5); + stack.push(1); + EXPECT_FALSE(stack.is_empty()); + EXPECT_EQ(stack.top(), 1); + stack.push(2); + EXPECT_EQ(stack.top(), 2); + stack.push(3); + EXPECT_EQ(stack.top(), 3); +} +TEST(StackTest, Pop) { + Stack stack(5); + stack.push(1); + stack.push(2); + stack.push(3); + EXPECT_EQ(stack.top(), 3); + stack.pop(); + EXPECT_EQ(stack.top(), 2); + stack.pop(); + EXPECT_EQ(stack.top(), 1); + stack.pop(); + EXPECT_TRUE(stack.is_empty()); +} +TEST(StackTest, PopEmptyStack) { + Stack stack(5); + EXPECT_THROW(stack.pop(), std::logic_error); + stack.push(1); + stack.pop(); + EXPECT_THROW(stack.pop(), std::logic_error); +} +TEST(StackTest, TopEmptyStack) { + Stack stack(5); + EXPECT_THROW(stack.top(), std::logic_error); +} +TEST(StackTest, Overflow) { + Stack stack(3); + stack.push(1); + stack.push(2); + stack.push(3); + EXPECT_TRUE(stack.is_full()); + EXPECT_THROW(stack.push(4), std::logic_error); +} +TEST(StackTest, IsEmpty) { + Stack stack(5); + EXPECT_TRUE(stack.is_empty()); + stack.push(1); + EXPECT_FALSE(stack.is_empty()); + stack.pop(); + EXPECT_TRUE(stack.is_empty()); +} +TEST(StackTest, IsFull) { + Stack stack(2); + EXPECT_FALSE(stack.is_full()); + stack.push(1); + EXPECT_FALSE(stack.is_full()); + stack.push(2); + EXPECT_TRUE(stack.is_full()); + stack.pop(); + EXPECT_FALSE(stack.is_full()); +} +TEST(StackTest, Clear) { + Stack stack(5); + for (int i = 0; i < 4; i++) { + stack.push(i + 1); + } + EXPECT_FALSE(stack.is_empty()); + stack.clear(); + EXPECT_TRUE(stack.is_empty()); + EXPECT_THROW(stack.top(), std::logic_error); +} +TEST(StackTest, SequenceOperations) { + Stack stack(10); + stack.push(1); + stack.push(2); + EXPECT_EQ(stack.top(), 2); + stack.pop(); + EXPECT_EQ(stack.top(), 1); + stack.push(3); + EXPECT_EQ(stack.top(), 3); +} +TEST(StackTest, DifferentDataTypes) { + Stack doubleStack(5); + doubleStack.push(3.14); + doubleStack.push(2.71); + EXPECT_DOUBLE_EQ(doubleStack.top(), 2.71); + Stack stringStack(5); + stringStack.push("hello"); + stringStack.push("world"); + EXPECT_EQ(stringStack.top(), "world"); +} +TEST(StackTest, LastInFirstOut) { + Stack stack(5); + stack.push(1); + stack.push(2); + stack.push(3); + EXPECT_EQ(stack.top(), 3); + stack.pop(); + EXPECT_EQ(stack.top(), 2); + stack.pop(); + EXPECT_EQ(stack.top(), 1); + stack.pop(); + EXPECT_TRUE(stack.is_empty()); +} \ No newline at end of file