From 726ef59331b1d96d323cf4554482a17e792278c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D1=80=D0=B8=D0=B3=D0=BE=D1=80=D1=8C=D0=B5=D0=B2=20?= =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Wed, 8 Oct 2025 14:28:53 +0300 Subject: [PATCH 01/11] add lib stack and add first template for class Stack --- CMakeLists.txt | 3 ++- lib_stack/CMakeLists.txt | 1 + lib_stack/stack.cpp | 0 lib_stack/stack.h | 19 +++++++++++++++++++ tests/tests_stack.cpp | 11 +++++++++++ 5 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 lib_stack/CMakeLists.txt create mode 100644 lib_stack/stack.cpp create mode 100644 lib_stack/stack.h create mode 100644 tests/tests_stack.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fb5abf3a..c587bba8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,8 @@ include(cmake/function.cmake) # подхватываем функции, # для простоты мы объединили наборы команд для создания статической библиотеки # и для создания исполняемого проекта в отдельные функции -add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_easy_example) +add_subdirectory(lib_stack) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main 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..e58e171e --- /dev/null +++ b/lib_stack/stack.h @@ -0,0 +1,19 @@ +#ifndef STACK +#define STACK + +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; + } +}; + +#endif \ No newline at end of file diff --git a/tests/tests_stack.cpp b/tests/tests_stack.cpp new file mode 100644 index 00000000..f2eb14f6 --- /dev/null +++ b/tests/tests_stack.cpp @@ -0,0 +1,11 @@ +#include +#include "../lib_stack/stack.h" + +TEST(TestEasyExampleLib, can_create_with_init_construct) { + // Arrange + int x = 10; + int y = 2; + + // Act & Assert + ASSERT_NO_THROW(Stack s(10)); +} \ No newline at end of file From d248e2029bbdbae4296759b29c6793d2d6d1fd8f Mon Sep 17 00:00:00 2001 From: Wyss180 Date: Sun, 12 Oct 2025 00:40:32 +0300 Subject: [PATCH 02/11] add some files --- .vs/ASD/v17/.wsuo | Bin 0 -> 12800 bytes .vs/ASD/v17/DocumentLayout.json | 12 ++++++++++++ .vs/VSWorkspaceState.json | 7 +++++++ CMakeLists.txt | 1 + lib_queue/CMakeLists.txt | 1 + lib_queue/queue.cpp | 0 lib_queue/queue.h | 0 tests/tests_queue.cpp | 0 8 files changed, 21 insertions(+) create mode 100644 .vs/ASD/v17/.wsuo create mode 100644 .vs/ASD/v17/DocumentLayout.json create mode 100644 .vs/VSWorkspaceState.json create mode 100644 lib_queue/CMakeLists.txt create mode 100644 lib_queue/queue.cpp create mode 100644 lib_queue/queue.h create mode 100644 tests/tests_queue.cpp diff --git a/.vs/ASD/v17/.wsuo b/.vs/ASD/v17/.wsuo new file mode 100644 index 0000000000000000000000000000000000000000..ab87500f40bcab4803117968084ce6184a9a7c62 GIT binary patch literal 12800 zcmeI2OLH4V5XVPO0t5&U9sxoECYWF#GJeL6f#Ae;0#%rVIB}@L9Bj!>geA)*$$1pt zgcE!NxNuCRD5{{igbTMEfD>H!2E_dSvl?l&mR2i?q_UKHt9NH+XQrp8r+a!HzuemU z+t=Uj|J?-OxY=RuZ0$A=_|g-;uzA9mhlwlg&eqnJekn|_3o+_}b0*JIGQDQjtn)3H z>k?&T*k^WCWWK9Osi_?Yzx-zMcH$A`d(z8%7K(ZEx%mLduTl+U034w1ET!Wpv(m8{9Y zzwnZe@(d{jf5AFo(ceva4;YpIY4SR~ev0rveg+6XQ?5(NPnW~e@ka^o0UrY&2i1pr zL5cENQ1Vy4eS9A(hgC-x?%y7`m-;_=`#?qiZ))HGPXF$u{-1(wSO0DIS8S*3f$V_v z_c_8&mmegoG(njD%LaM5YTwV3E?ZEW+Kt^WJs{cELnn91Reql4>@fLj9?@K(xkL6} z^MS^Z<3>5-vHkPkAO*V0DKD^1c$(3 za0DC$$H1dtJ)V^IZpgo2nfpaXce5R5%rf5B9DYZ^Oym8?2VAl5qFFE#^j0_=!vE0t zaBU3F?fpH@NB)Xn8sBHh6nPf#c2>;QZLRR~HF~$>e@V`+z8PpP7XGdVMK# znOMj;(qA(l!fTPSH&4&Y2QQhF z^^BXzK=RkzC3_W>{}bd@dj$(nJ#YIU%Q(oh3YfR!;0opUy;`YFq`Mro}^9)*9c2Q}ZT4N>T8>^u2~(OYWZL>f6~9$Ti*^=RH)j~}(oXe55U{@$+EMw}+~?LGVf6j_SDgbsV)Rwz!1zzd&vI+_ zVEgLDWv^ZT*Zbc}+9$W%OwvlJYTmwWGf>g=VwDGZhVbM>U%(&zYk&Sdvqz?( zB`B7bQftXfuHEu~ebK*B{Po8h?Urw;v2`*BeO?#u`v2a#$k~sNN56CLWbyzF2n z^kv6YzFNn|6w%1gY5OA+3d!i!LjEkBr1|TK8kP_F9XM?!&0^Uf)0$9oO)s;525(Gr z{~~KedB$3i6v0(yV%ckX@0;Y#64M%Dleto!+ajy;L2#Im)|WXRd2jM+uamYw>SD#a z^y;54rw*~A9{}|p!DCfTYZlST5zlrcAB%0~t(JHdF8CjS&u z9=wy(H6*fuhI>{iE_T(8AZL}d+mMa5G_If((vAXrWY}NR$oe^^BTKv#tnZ>dDXqZ8 zOYo3EpFiD=^Pf3$&Rj6sGpRlA^6$BX8IQwloIjkRLRmXOl=J7> z6Cbafd-p?M_EXonqMm;oBQLhdLXf`hVd~sf-h1Oy&vIct@Za+NOWkU4=YRF+dp97o zx0JT`QN!B9`Io)VsymQT`5zCVubnpOqsGG~GikFkXz{N*nUZHz`r`d7dkJ^D{Hye@ z<1Ok$JWKAz;QC+pd!o`0yMHl9ujinud&vH?u|{L?NE`B(&vCxYQc(ULO|87Vo4_X+ zi5pl(t?;#HsZ>8m{^Hw#|6il9?$$ZKOScWQ1ESMpQ4!^Hq)G0&5AZRgKpvIu#uO`O lpw*fu+R%T0|5s~jFVsE%>+JkbdaJ#6ot(FG{@CgH;lCya$hH6g literal 0 HcmV?d00001 diff --git a/.vs/ASD/v17/DocumentLayout.json b/.vs/ASD/v17/DocumentLayout.json new file mode 100644 index 00000000..92ead96d --- /dev/null +++ b/.vs/ASD/v17/DocumentLayout.json @@ -0,0 +1,12 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\Pylax\\ASD\\", + "Documents": [], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [] + } + ] +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 00000000..97a23c5a --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,7 @@ +{ + "ExpandedNodes": [ + "" + ], + "SelectedNode": "\\C:\\Users\\Pylax\\ASD", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index c587bba8..ccd6113c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ include(cmake/function.cmake) # подхватываем функции, # и для создания исполняемого проекта в отдельные функции add_subdirectory(lib_easy_example) +add_subdirectory(lib_queue) add_subdirectory(lib_stack) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main 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..e69de29b diff --git a/tests/tests_queue.cpp b/tests/tests_queue.cpp new file mode 100644 index 00000000..e69de29b From f600dbb20a844d78f1781244b6eb432aa4d38048 Mon Sep 17 00:00:00 2001 From: Wyss180 Date: Wed, 15 Oct 2025 13:20:49 +0300 Subject: [PATCH 03/11] Delete extra files --- .vs/ASD/v17/.wsuo | Bin 12800 -> 0 bytes .vs/ASD/v17/DocumentLayout.json | 12 ------------ .vs/VSWorkspaceState.json | 7 ------- 3 files changed, 19 deletions(-) delete mode 100644 .vs/ASD/v17/.wsuo delete mode 100644 .vs/ASD/v17/DocumentLayout.json delete mode 100644 .vs/VSWorkspaceState.json diff --git a/.vs/ASD/v17/.wsuo b/.vs/ASD/v17/.wsuo deleted file mode 100644 index ab87500f40bcab4803117968084ce6184a9a7c62..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12800 zcmeI2OLH4V5XVPO0t5&U9sxoECYWF#GJeL6f#Ae;0#%rVIB}@L9Bj!>geA)*$$1pt zgcE!NxNuCRD5{{igbTMEfD>H!2E_dSvl?l&mR2i?q_UKHt9NH+XQrp8r+a!HzuemU z+t=Uj|J?-OxY=RuZ0$A=_|g-;uzA9mhlwlg&eqnJekn|_3o+_}b0*JIGQDQjtn)3H z>k?&T*k^WCWWK9Osi_?Yzx-zMcH$A`d(z8%7K(ZEx%mLduTl+U034w1ET!Wpv(m8{9Y zzwnZe@(d{jf5AFo(ceva4;YpIY4SR~ev0rveg+6XQ?5(NPnW~e@ka^o0UrY&2i1pr zL5cENQ1Vy4eS9A(hgC-x?%y7`m-;_=`#?qiZ))HGPXF$u{-1(wSO0DIS8S*3f$V_v z_c_8&mmegoG(njD%LaM5YTwV3E?ZEW+Kt^WJs{cELnn91Reql4>@fLj9?@K(xkL6} z^MS^Z<3>5-vHkPkAO*V0DKD^1c$(3 za0DC$$H1dtJ)V^IZpgo2nfpaXce5R5%rf5B9DYZ^Oym8?2VAl5qFFE#^j0_=!vE0t zaBU3F?fpH@NB)Xn8sBHh6nPf#c2>;QZLRR~HF~$>e@V`+z8PpP7XGdVMK# znOMj;(qA(l!fTPSH&4&Y2QQhF z^^BXzK=RkzC3_W>{}bd@dj$(nJ#YIU%Q(oh3YfR!;0opUy;`YFq`Mro}^9)*9c2Q}ZT4N>T8>^u2~(OYWZL>f6~9$Ti*^=RH)j~}(oXe55U{@$+EMw}+~?LGVf6j_SDgbsV)Rwz!1zzd&vI+_ zVEgLDWv^ZT*Zbc}+9$W%OwvlJYTmwWGf>g=VwDGZhVbM>U%(&zYk&Sdvqz?( zB`B7bQftXfuHEu~ebK*B{Po8h?Urw;v2`*BeO?#u`v2a#$k~sNN56CLWbyzF2n z^kv6YzFNn|6w%1gY5OA+3d!i!LjEkBr1|TK8kP_F9XM?!&0^Uf)0$9oO)s;525(Gr z{~~KedB$3i6v0(yV%ckX@0;Y#64M%Dleto!+ajy;L2#Im)|WXRd2jM+uamYw>SD#a z^y;54rw*~A9{}|p!DCfTYZlST5zlrcAB%0~t(JHdF8CjS&u z9=wy(H6*fuhI>{iE_T(8AZL}d+mMa5G_If((vAXrWY}NR$oe^^BTKv#tnZ>dDXqZ8 zOYo3EpFiD=^Pf3$&Rj6sGpRlA^6$BX8IQwloIjkRLRmXOl=J7> z6Cbafd-p?M_EXonqMm;oBQLhdLXf`hVd~sf-h1Oy&vIct@Za+NOWkU4=YRF+dp97o zx0JT`QN!B9`Io)VsymQT`5zCVubnpOqsGG~GikFkXz{N*nUZHz`r`d7dkJ^D{Hye@ z<1Ok$JWKAz;QC+pd!o`0yMHl9ujinud&vH?u|{L?NE`B(&vCxYQc(ULO|87Vo4_X+ zi5pl(t?;#HsZ>8m{^Hw#|6il9?$$ZKOScWQ1ESMpQ4!^Hq)G0&5AZRgKpvIu#uO`O lpw*fu+R%T0|5s~jFVsE%>+JkbdaJ#6ot(FG{@CgH;lCya$hH6g diff --git a/.vs/ASD/v17/DocumentLayout.json b/.vs/ASD/v17/DocumentLayout.json deleted file mode 100644 index 92ead96d..00000000 --- a/.vs/ASD/v17/DocumentLayout.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "Version": 1, - "WorkspaceRootPath": "C:\\Users\\Pylax\\ASD\\", - "Documents": [], - "DocumentGroupContainers": [ - { - "Orientation": 0, - "VerticalTabListWidth": 256, - "DocumentGroups": [] - } - ] -} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json deleted file mode 100644 index 97a23c5a..00000000 --- a/.vs/VSWorkspaceState.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "ExpandedNodes": [ - "" - ], - "SelectedNode": "\\C:\\Users\\Pylax\\ASD", - "PreviewInSolutionExplorer": false -} \ No newline at end of file From d8908da72febc4d47455ed4959810373f54e0349 Mon Sep 17 00:00:00 2001 From: Wyss180 Date: Wed, 15 Oct 2025 14:32:10 +0300 Subject: [PATCH 04/11] added realization of class Queue with tests --- lib_queue/queue.h | 51 +++++++++++++++++++++++++++++++++++++ tests/tests_queue.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/lib_queue/queue.h b/lib_queue/queue.h index e69de29b..30c9b49b 100644 --- a/lib_queue/queue.h +++ 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/tests/tests_queue.cpp b/tests/tests_queue.cpp index e69de29b..dcf1af54 100644 --- a/tests/tests_queue.cpp +++ 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); +} From 0b11a3ec4f0d6625b5aec59e2ddbf8ade10b5004 Mon Sep 17 00:00:00 2001 From: Wyss180 Date: Wed, 22 Oct 2025 14:24:26 +0300 Subject: [PATCH 05/11] add algorithms --- CMakeLists.txt | 3 +- lib_algorithms/CMakeLists.txt | 2 + lib_algorithms/algorithms.cpp | 24 +++++++++ lib_algorithms/algorithms.h | 7 +++ lib_stack/stack.h | 65 +++++++++++++++++++++---- tests/tests_algorithms.cpp | 9 ++++ tests/tests_stack.cpp | 92 ++++++++++++++++++++++++++++++++--- 7 files changed, 186 insertions(+), 16 deletions(-) create mode 100644 lib_algorithms/CMakeLists.txt create mode 100644 lib_algorithms/algorithms.cpp create mode 100644 lib_algorithms/algorithms.h create mode 100644 tests/tests_algorithms.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ccd6113c..07d86ca6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,8 @@ include(cmake/function.cmake) # подхватываем функции, add_subdirectory(lib_easy_example) add_subdirectory(lib_queue) -add_subdirectory(lib_stack) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_stack) +add_subdirectory(lib_algorithms) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main 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..5aab5388 --- /dev/null +++ b/lib_algorithms/algorithms.cpp @@ -0,0 +1,24 @@ +#include +#include +#include "algorithms.h" + +bool check_breckets(std::string str) { + std::stack stack; + + for (char c : str) { + if (c == ' ' || c == '\t' || c == '\n') continue; + + if (c == '(' || c == '[' || c == '{') { + stack.push(c); + } + else if (c == ')' || c == ']' || c == '}') { + if (stack.empty()) 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_stack/stack.h b/lib_stack/stack.h index e58e171e..bb13cc42 100644 --- a/lib_stack/stack.h +++ b/lib_stack/stack.h @@ -1,19 +1,66 @@ #ifndef STACK #define STACK +#include + template class Stack { - T* _data; - int _size; - int _top; + T* _data; + int _size; + int _top; public: - Stack(int size = 20) :_size(size), _top(-1) { - _data = new T[size]; - } - ~Stack() { - delete[] _data; - } + 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/tests/tests_algorithms.cpp b/tests/tests_algorithms.cpp new file mode 100644 index 00000000..3d82c286 --- /dev/null +++ b/tests/tests_algorithms.cpp @@ -0,0 +1,9 @@ +#include +#include "../lib_algorithms/algorithms.h" + + +TEST(Brackets, empty) { EXPECT_TRUE(check_breckets("")); } +TEST(Brackets, with_spaces) { EXPECT_TRUE(check_breckets(" ( ) [ ] { } ")); } +TEST(Brackets, tabs_and_newlines) { EXPECT_TRUE(check_breckets("\n[\n]")); } +TEST(Brackets, letters_still_error) { EXPECT_FALSE(check_breckets("(a)")); } +TEST(Brackets, numbers_still_error) { EXPECT_FALSE(check_breckets("(1)")); } \ No newline at end of file diff --git a/tests/tests_stack.cpp b/tests/tests_stack.cpp index f2eb14f6..bf446844 100644 --- a/tests/tests_stack.cpp +++ b/tests/tests_stack.cpp @@ -1,11 +1,91 @@ #include #include "../lib_stack/stack.h" -TEST(TestEasyExampleLib, can_create_with_init_construct) { - // Arrange - int x = 10; - int y = 2; +TEST(StackTest, create_stack) { + ASSERT_NO_THROW(Stack s(5)); +} - // Act & Assert - ASSERT_NO_THROW(Stack s(10)); +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 From 503c3b0afcd8e9b5e08f9e18b34043af3f7964e9 Mon Sep 17 00:00:00 2001 From: Wyss180 Date: Thu, 23 Oct 2025 01:28:40 +0300 Subject: [PATCH 06/11] fixed algorithms --- lib_algorithms/algorithms.cpp | 20 ++++++++++--- tests/tests_algorithms.cpp | 53 +++++++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/lib_algorithms/algorithms.cpp b/lib_algorithms/algorithms.cpp index 5aab5388..ea78f634 100644 --- a/lib_algorithms/algorithms.cpp +++ b/lib_algorithms/algorithms.cpp @@ -1,18 +1,30 @@ #include -#include #include "algorithms.h" +#include + +using std::string; bool check_breckets(std::string str) { std::stack stack; - for (char c : str) { - if (c == ' ' || c == '\t' || c == '\n') continue; + 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 (stack.empty()) { + return false; + } + + if ((c == ')' && stack.top() != '(') || + (c == ']' && stack.top() != '[') || + (c == '}' && stack.top() != '{')) { + return false; + } stack.pop(); } else { diff --git a/tests/tests_algorithms.cpp b/tests/tests_algorithms.cpp index 3d82c286..27d7cf0d 100644 --- a/tests/tests_algorithms.cpp +++ b/tests/tests_algorithms.cpp @@ -2,8 +2,51 @@ #include "../lib_algorithms/algorithms.h" -TEST(Brackets, empty) { EXPECT_TRUE(check_breckets("")); } -TEST(Brackets, with_spaces) { EXPECT_TRUE(check_breckets(" ( ) [ ] { } ")); } -TEST(Brackets, tabs_and_newlines) { EXPECT_TRUE(check_breckets("\n[\n]")); } -TEST(Brackets, letters_still_error) { EXPECT_FALSE(check_breckets("(a)")); } -TEST(Brackets, numbers_still_error) { EXPECT_FALSE(check_breckets("(1)")); } \ No newline at end of file +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 From 0f6c554c0169ba56ed96de276a984bec2b5e2505 Mon Sep 17 00:00:00 2001 From: Wyss180 Date: Fri, 24 Oct 2025 04:52:22 +0300 Subject: [PATCH 07/11] add some files --- CMakeLists.txt | 3 ++- lib_list/CMakeLists.txt | 1 + lib_list/list.cpp | 1 + lib_list/list.h | 0 tests/tests_list.cpp | 0 5 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 lib_list/CMakeLists.txt create mode 100644 lib_list/list.cpp create mode 100644 lib_list/list.h create mode 100644 tests/tests_list.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 07d86ca6..e3fdebd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,8 @@ include(cmake/function.cmake) # подхватываем функции, add_subdirectory(lib_easy_example) add_subdirectory(lib_queue) add_subdirectory(lib_stack) -add_subdirectory(lib_algorithms) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_algorithms) +add_subdirectory(lib_list) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example add_subdirectory(main) # подключаем дополнительный CMakeLists.txt из подкаталога с именем main 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..e69de29b diff --git a/tests/tests_list.cpp b/tests/tests_list.cpp new file mode 100644 index 00000000..e69de29b From 800e6de168f72ec3a715371938a26a47b4819836 Mon Sep 17 00:00:00 2001 From: Wyss180 Date: Tue, 28 Oct 2025 17:15:18 +0300 Subject: [PATCH 08/11] Added list implementation and tests --- lib_list/list.h | 271 +++++++++++++++++++++++++++++++++++++++ tests/tests_list.cpp | 295 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 566 insertions(+) diff --git a/lib_list/list.h b/lib_list/list.h index e69de29b..0b5fc88b 100644 --- a/lib_list/list.h +++ b/lib_list/list.h @@ -0,0 +1,271 @@ +#ifndef QUEUE +#define QUEUE + +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(); + Node* begin(); + Node* end(); +}; +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; +} + +template +Node* List::begin() { + return _head; +} + +template +Node* List::end() { + return nullptr; +} + +#endif \ No newline at end of file diff --git a/tests/tests_list.cpp b/tests/tests_list.cpp index e69de29b..2782e6c9 100644 --- a/tests/tests_list.cpp +++ b/tests/tests_list.cpp @@ -0,0 +1,295 @@ +#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, iteration_with_begin_end) { + List list; + list.push_back(1); + list.push_back(2); + list.push_back(3); + + std::vector result; + for (Node* current = list.begin(); current != list.end(); current = current->next) { + result.push_back(current->value); + } + + std::vector expected = { 1, 2, 3 }; + EXPECT_EQ(result, expected); +} + +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); +} \ No newline at end of file From 8175585dfdae9fb7cb553aa241ab969fb74193fe Mon Sep 17 00:00:00 2001 From: Wyss180 Date: Wed, 29 Oct 2025 14:33:36 +0300 Subject: [PATCH 09/11] Added iterator --- lib_list/list.h | 78 ++++++++++++++++++++++++++++++++++++-------- tests/tests_list.cpp | 71 ++++++++++++++++++++++++++++++++-------- 2 files changed, 122 insertions(+), 27 deletions(-) diff --git a/lib_list/list.h b/lib_list/list.h index 0b5fc88b..19047af8 100644 --- a/lib_list/list.h +++ b/lib_list/list.h @@ -1,5 +1,5 @@ -#ifndef QUEUE -#define QUEUE +#ifndef LIST +#define LIST template struct Node { @@ -33,8 +33,60 @@ class List { T& back(); int size() const; void clear(); - Node* begin(); - Node* end(); + //Node* begin(); + //Node* end(); + + + + 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) {} @@ -258,14 +310,14 @@ void List::clear() { _count = 0; } -template -Node* List::begin() { - return _head; -} - -template -Node* List::end() { - return nullptr; -} +//template +//Node* List::begin() { +// return _head; +//} +// +//template +//Node* List::end() { +// return nullptr; +//} #endif \ No newline at end of file diff --git a/tests/tests_list.cpp b/tests/tests_list.cpp index 2782e6c9..2df2d89e 100644 --- a/tests/tests_list.cpp +++ b/tests/tests_list.cpp @@ -205,20 +205,20 @@ TEST(ListTest, assignment_operator) { EXPECT_EQ(list2.back(), 2); } -TEST(ListTest, iteration_with_begin_end) { - List list; - list.push_back(1); - list.push_back(2); - list.push_back(3); - - std::vector result; - for (Node* current = list.begin(); current != list.end(); current = current->next) { - result.push_back(current->value); - } - - std::vector expected = { 1, 2, 3 }; - EXPECT_EQ(result, expected); -} +//TEST(ListTest, iteration_with_begin_end) { +// List list; +// list.push_back(1); +// list.push_back(2); +// list.push_back(3); +// +// std::vector result; +// for (Node* current = list.begin(); current != list.end(); current = current->next) { +// result.push_back(current->value); +// } +// +// std::vector expected = { 1, 2, 3 }; +// EXPECT_EQ(result, expected); +//} TEST(ListTest, pop_front_until_empty) { List list; @@ -292,4 +292,47 @@ TEST(ListTest, double_list) { 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 From 0b48632f3d0e6f467ebc70070fc820a9eefc2af0 Mon Sep 17 00:00:00 2001 From: Wyss180 Date: Fri, 31 Oct 2025 00:34:07 +0300 Subject: [PATCH 10/11] added some fixes in list, added new branchs and files(doubly linked list and tvector), added iterator in tvector+tests --- CMakeLists.txt | 4 +- lib_doubly_linked_list/CMakeLists.txt | 1 + lib_doubly_linked_list/doubly_linked_list.cpp | 0 lib_doubly_linked_list/doubly_linked_list.h | 0 lib_list/list.h | 12 - lib_tvector/CMakeLists.txt | 1 + lib_tvector/tvector.cpp | 1 + lib_tvector/tvector.h | 395 ++++++++++++++++++ tests/tests_doubly_linked_list.cpp | 0 tests/tests_list.cpp | 15 - tests/tests_tvector.cpp | 138 ++++++ 11 files changed, 539 insertions(+), 28 deletions(-) create mode 100644 lib_doubly_linked_list/CMakeLists.txt create mode 100644 lib_doubly_linked_list/doubly_linked_list.cpp create mode 100644 lib_doubly_linked_list/doubly_linked_list.h create mode 100644 lib_tvector/CMakeLists.txt create mode 100644 lib_tvector/tvector.cpp create mode 100644 lib_tvector/tvector.h create mode 100644 tests/tests_doubly_linked_list.cpp create mode 100644 tests/tests_tvector.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e3fdebd0..4b0ab672 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,9 @@ add_subdirectory(lib_easy_example) add_subdirectory(lib_queue) add_subdirectory(lib_stack) add_subdirectory(lib_algorithms) -add_subdirectory(lib_list) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +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_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/list.h b/lib_list/list.h index 19047af8..63551463 100644 --- a/lib_list/list.h +++ b/lib_list/list.h @@ -33,8 +33,6 @@ class List { T& back(); int size() const; void clear(); - //Node* begin(); - //Node* end(); @@ -310,14 +308,4 @@ void List::clear() { _count = 0; } -//template -//Node* List::begin() { -// return _head; -//} -// -//template -//Node* List::end() { -// return nullptr; -//} - #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/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 index 2df2d89e..27696891 100644 --- a/tests/tests_list.cpp +++ b/tests/tests_list.cpp @@ -205,21 +205,6 @@ TEST(ListTest, assignment_operator) { EXPECT_EQ(list2.back(), 2); } -//TEST(ListTest, iteration_with_begin_end) { -// List list; -// list.push_back(1); -// list.push_back(2); -// list.push_back(3); -// -// std::vector result; -// for (Node* current = list.begin(); current != list.end(); current = current->next) { -// result.push_back(current->value); -// } -// -// std::vector expected = { 1, 2, 3 }; -// EXPECT_EQ(result, expected); -//} - TEST(ListTest, pop_front_until_empty) { List list; list.push_back(1); 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 From c9df0306d2b457008d06b3607af5c4bbfb09611d Mon Sep 17 00:00:00 2001 From: Wyss180 Date: Wed, 5 Nov 2025 14:23:55 +0300 Subject: [PATCH 11/11] realise DSU --- CMakeLists.txt | 3 ++- lib_DSU/CMakeLists.txt | 1 + lib_DSU/DSU.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++ lib_DSU/DSU.h | 22 +++++++++++++++++++ tests/test_DSU.cpp | 46 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 lib_DSU/CMakeLists.txt create mode 100644 lib_DSU/DSU.cpp create mode 100644 lib_DSU/DSU.h create mode 100644 tests/test_DSU.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fb5abf3a..30ca7a53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,8 @@ include(cmake/function.cmake) # подхватываем функции, # для простоты мы объединили наборы команд для создания статической библиотеки # и для создания исполняемого проекта в отдельные функции -add_subdirectory(lib_easy_example) # подключаем дополнительный CMakeLists.txt из подкаталога с именем lib_easy_example +add_subdirectory(lib_easy_example) +add_subdirectory(lib_DSU) # подключаем дополнительный 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/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