From cf6becdaa1e447d3cd8d00574cd0a7631d2069ad Mon Sep 17 00:00:00 2001 From: love Date: Sat, 1 Mar 2025 08:07:20 +0000 Subject: [PATCH 01/34] task_03 --- task_02/src/stack.cpp | 67 +++++++++++++++++++------ task_02/src/stack.hpp | 84 ++++++++++++++++++++++++++++---- task_02/src/test.cpp | 6 +-- task_03/src/days_before_hot.cpp | 20 ++++++++ task_03/src/days_before_hot.h | 5 ++ task_03/src/main | Bin 0 -> 166760 bytes task_03/src/main.cpp | 14 +++++- task_03/src/test.cpp | 38 +++++++++++++-- 8 files changed, 201 insertions(+), 33 deletions(-) create mode 100644 task_03/src/days_before_hot.cpp create mode 100644 task_03/src/days_before_hot.h create mode 100755 task_03/src/main diff --git a/task_02/src/stack.cpp b/task_02/src/stack.cpp index 8ca8990..8c75731 100644 --- a/task_02/src/stack.cpp +++ b/task_02/src/stack.cpp @@ -1,21 +1,58 @@ -#include "stack.hpp" +// #include "stack.hpp" -#include +// #include -void Stack::Push(int value) { data_.push(value); } +// template +// void Stack::Push(T value) { +// if (!head) { +// head = new Node; +// head->value = value; +// } else { +// Node* new_head = new Node; +// new_head->prev = head; +// new_head->value = value; +// head = new_head; +// } +// } -int Stack::Pop() { - auto result = data_.top(); - data_.pop(); - return result; -} +// template +// T Stack::Pop() { +// T val = head->value; +// head = head->prev; +// return val; +// } -void MinStack::Push(int value) { data_.push_back(value); } +// template +// requires(std::totally_ordered) +// void MinStack::Push(T value) { +// if (!head) { +// head = new Node; +// head->value = value; +// head_min = new Node; +// head_min->value = value; +// } else { +// Node* new_head = new Node; +// Node* new_head_min = new Node; +// new_head->prev = head; +// new_head->value = value; +// new_head_min->prev = head_min; +// new_head_min->value = std::min(head->value, value); +// head = new_head; +// head_min = new_head_min; +// } +// } -int MinStack::Pop() { - auto result = data_.back(); - data_.pop_back(); - return result; -} +// template +// requires(std::totally_ordered) +// T MinStack::Pop() { +// T val = head->value; +// head = head->prev; +// head_min = head_min->prev; +// return val; +// } -int MinStack::GetMin() { return *std::min_element(data_.begin(), data_.end()); } \ No newline at end of file +// template +// requires(std::totally_ordered) +// T MinStack::GetMin() { +// return head_min->value; +// } \ No newline at end of file diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp index 138ec40..0b77b4b 100644 --- a/task_02/src/stack.hpp +++ b/task_02/src/stack.hpp @@ -1,23 +1,89 @@ #pragma once -#include -#include +#include +#include +template +struct Node { + T value; + Node* prev = nullptr; +}; + +template class Stack { public: - void Push(int value); - int Pop(); + Stack(){}; + void Push(T value); + T Pop(); private: - std::stack data_; + Node* head = nullptr; }; +template + requires(std::totally_ordered) class MinStack { public: - void Push(int value); - int Pop(); - int GetMin(); + void Push(T value); + T Pop(); + T GetMin(); private: - std::vector data_; + Node* head = nullptr; + Node* head_min = nullptr; }; + +template +void Stack::Push(T value) { + if (!head) { + head = new Node; + head->value = value; + } else { + Node* new_head = new Node; + new_head->prev = head; + new_head->value = value; + head = new_head; + } +} + +template +T Stack::Pop() { + T val = head->value; + head = head->prev; + return val; +} + +template + requires(std::totally_ordered) +void MinStack::Push(T value) { + if (!head) { + head = new Node; + head->value = value; + head_min = new Node; + head_min->value = value; + } else { + Node* new_head = new Node; + Node* new_head_min = new Node; + new_head->prev = head; + new_head->value = value; + new_head_min->prev = head_min; + new_head_min->value = std::min(head->value, value); + head = new_head; + head_min = new_head_min; + } +} + +template + requires(std::totally_ordered) +T MinStack::Pop() { + T val = head->value; + head = head->prev; + head_min = head_min->prev; + return val; +} + +template + requires(std::totally_ordered) +T MinStack::GetMin() { + return head_min->value; +} \ No newline at end of file diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index 54e7ce9..f81ba58 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -1,12 +1,10 @@ #include -#include - #include "stack.hpp" TEST(StackTest, Simple) { - Stack stack; + Stack stack{}; stack.Push(1); // Stack [1] ASSERT_EQ(stack.Pop(), 1); // Stack [] stack.Push(1); // Stack [1] @@ -22,7 +20,7 @@ TEST(StackTest, Simple) { } TEST(MinStackTest, Simple) { - MinStack stack; + MinStack stack{}; stack.Push(1); // Stack [1] ASSERT_EQ(stack.GetMin(), 1); ASSERT_EQ(stack.Pop(), 1); // Stack [] diff --git a/task_03/src/days_before_hot.cpp b/task_03/src/days_before_hot.cpp new file mode 100644 index 0000000..9c4556d --- /dev/null +++ b/task_03/src/days_before_hot.cpp @@ -0,0 +1,20 @@ +#include "days_before_hot.h" + +std::vector days_before_hot(std::vector temperatures) { + std::vector days_before_h(temperatures.size()); + std::stack> memory{}; + int size = temperatures.size() - 1; + for (int i{size}; i >= 0; --i) { + while (!(memory.empty()) and (memory.top()[0] <= temperatures[i])) { + memory.pop(); + } + if (memory.empty()) { + days_before_h[i] = 0; + } else { + days_before_h[i] = memory.top()[1] - i; + } + std::vector day{temperatures[i], static_cast(i)}; + memory.push(day); + } + return days_before_h; +} \ No newline at end of file diff --git a/task_03/src/days_before_hot.h b/task_03/src/days_before_hot.h new file mode 100644 index 0000000..1ed1516 --- /dev/null +++ b/task_03/src/days_before_hot.h @@ -0,0 +1,5 @@ +#include +#include +#include + +std::vector days_before_hot(std::vector temperatures); \ No newline at end of file diff --git a/task_03/src/main b/task_03/src/main new file mode 100755 index 0000000000000000000000000000000000000000..d74802a5f31c3c2e7d3ad399806043caa90ce0b9 GIT binary patch literal 166760 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%0A3N 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 NcKzeY1<9Yq{{ +// #include +// #include +// #include -int main() { return 0; } +#include "days_before_hot.h" + +int main() { + // std::vector temp{5, 7, 5, 3, 10, 0, 2, -1, 3}; + // std::vector ans{days_before_hot(temp)}; + // for (auto day : ans) { + // std::cout << day << std::endl; + // } +} diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index ef5a86a..a87e765 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,8 +1,40 @@ #include -#include "topology_sort.hpp" +#include "days_before_hot.h" -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +TEST(first_test, ints) { + std::vector temp{5, 7, 5, 3, 10, 0, 2, -1, 3}; + std::vector ans{1, 3, 2, 1, 0, 1, 2, 1, 0}; + ASSERT_EQ(days_before_hot(temp), ans); } + +TEST(second_test, doubles) { + std::vector temp{5.1, 7.656, 5.0, 3, 10, -729.3, 2, -1.4, 3.2}; + std::vector ans{1, 3, 2, 1, 0, 1, 2, 1, 0}; + ASSERT_EQ(days_before_hot(temp), ans); +} + +TEST(third_test, no_hot) { + std::vector temp{5, 4.7, 4.3, 3, 2, 1.3}; + std::vector ans{0, 0, 0, 0, 0, 0}; + ASSERT_EQ(days_before_hot(temp), ans); +} + +TEST(fourth_test, four) { + std::vector temp{5, 4, 3, 2, 1, 10}; + std::vector ans{5, 4, 3, 2, 1, 0}; + ASSERT_EQ(days_before_hot(temp), ans); +} + +TEST(fifth_test, one_number) { + std::vector temp{1}; + std::vector ans{0}; + ASSERT_EQ(days_before_hot(temp), ans); +} + +TEST(sixth_test, same_values) { + std::vector temp{1, 1, 2, 2, 5, 1, 7}; + std::vector ans{2, 1, 2, 1, 2, 1, 0}; + ASSERT_EQ(days_before_hot(temp), ans); +} \ No newline at end of file From 3fbabbcdfec3c516aac0151421a0ff858c9f7f42 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 15 Mar 2025 17:54:02 +0000 Subject: [PATCH 02/34] topic3 question1-2-3 theory --- doc/topic3/question1-2-3.md | 73 +++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 doc/topic3/question1-2-3.md diff --git a/doc/topic3/question1-2-3.md b/doc/topic3/question1-2-3.md new file mode 100644 index 0000000..a6a1f5c --- /dev/null +++ b/doc/topic3/question1-2-3.md @@ -0,0 +1,73 @@ +# **Определение дерева, дерева с корнем. Высота дерева, родительские, дочерние узлы, листья. Количество ребер.** + +**Дерево** - структура данных, представляющая набор вершин (узлов), соединенных ребрами. + +- *Родительский узел* - который имеет *дочерние узлы*. +- Самый "верхний" узел дерева (не имеющий родительских) называется *корнем (root)* +- Каждый узел (кроме корня) имеет ровно одного родителя. Узлы без потомков называются *листьями*. +- *Высота* дерева - длина самого длинного пути от корня до листа. +- *Количество ребер* в дереве всегда равно количеству узлов -1 (условно можно привязать к каждому узлу единственное ребро, соединяющее его с родителем. У корня такого нет -> N-1) + +--- +--- + +# **Обходы в глубину (Depth-First search, DFS). Pre-order, post-order и in-order для бинарных деревьев.** + +**Бинарное дерево** - в котором у каждого из родителей не больше 2 дочерних узлов. + +**Обход в глубину** предполагает движение от корня к листьям, проходя каждую ветвь до конца перед переходом к следующей. + +**Типы** (предполагают рекурсивный обход левой и правой веток для каждой вершины): + +- pre-oder +- post-oder +- in-oder + +--- +### **Pre-oder** + +*сначала вывод родителя, потом прохождение по ветвям* +Псевдокод: +```python +def foreach(root): + if root == None: # дошли до листьев + return + print(root.value) + foreach(root.left) + foreach(root.right) +``` + +--- +### **Post-oder** + +*сначала прохождение по ветвямб потом вывод родителя* +Псевдокод: +```python +def foreach(root): + if root == None: # дошли до листьев + return + foreach(root.left) + foreach(root.right) + print(root.value) +``` + +--- +### **In-oder** + +*вывод родителя между ветвями* +Псевдокод: +```python +def foreach(root): + if root == None: # дошли до листьев + return + foreach(root.left) + print(root.value) + foreach(root.right) +``` + + +--- +# **Обход в ширину (Breadth-First search, BFS)** + +**Обход в ширину** предполагает посещение всех узлов по уровням, начиная с корня (внутри уровня обход слеванаправо). +(аналогия: сначала дедушка, потом все родители, потм все дети, потом все внуки и т.п.) \ No newline at end of file From 6024697cfd31660f9abdc6d0acc9d39cb334ec59 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 15 Mar 2025 18:01:34 +0000 Subject: [PATCH 03/34] topic3 question1-2-3 theory better --- doc/topic3/question1-2-3.md | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/doc/topic3/question1-2-3.md b/doc/topic3/question1-2-3.md index a6a1f5c..8a1fb09 100644 --- a/doc/topic3/question1-2-3.md +++ b/doc/topic3/question1-2-3.md @@ -5,13 +5,12 @@ - *Родительский узел* - который имеет *дочерние узлы*. - Самый "верхний" узел дерева (не имеющий родительских) называется *корнем (root)* - Каждый узел (кроме корня) имеет ровно одного родителя. Узлы без потомков называются *листьями*. -- *Высота* дерева - длина самого длинного пути от корня до листа. +- *Высота* дерева - длина самого длинного пути от корня до листа (число ребер между нимиб например у дерева только из корня высота 0). - *Количество ребер* в дереве всегда равно количеству узлов -1 (условно можно привязать к каждому узлу единственное ребро, соединяющее его с родителем. У корня такого нет -> N-1) ---- --- -# **Обходы в глубину (Depth-First search, DFS). Pre-order, post-order и in-order для бинарных деревьев.** +# **Обходы в глубину (Depth-First Search, DFS). Pre-order, post-order и in-order для бинарных деревьев.** **Бинарное дерево** - в котором у каждого из родителей не больше 2 дочерних узлов. @@ -27,13 +26,14 @@ ### **Pre-oder** *сначала вывод родителя, потом прохождение по ветвям* -Псевдокод: + +псевдокод python: ```python def foreach(root): - if root == None: # дошли до листьев + if root == None: # дошли до листьев return - print(root.value) - foreach(root.left) + print(root.value) # значение родительского узла + foreach(root.left) # рекурсия foreach(root.right) ``` @@ -41,10 +41,11 @@ def foreach(root): ### **Post-oder** *сначала прохождение по ветвямб потом вывод родителя* -Псевдокод: + +псевдокод python: ```python def foreach(root): - if root == None: # дошли до листьев + if root == None: return foreach(root.left) foreach(root.right) @@ -55,10 +56,11 @@ def foreach(root): ### **In-oder** *вывод родителя между ветвями* -Псевдокод: + +псевдокод python: ```python def foreach(root): - if root == None: # дошли до листьев + if root == None: return foreach(root.left) print(root.value) @@ -67,7 +69,7 @@ def foreach(root): --- -# **Обход в ширину (Breadth-First search, BFS)** +## **Обход в ширину (Breadth-First Search, BFS)** -**Обход в ширину** предполагает посещение всех узлов по уровням, начиная с корня (внутри уровня обход слеванаправо). -(аналогия: сначала дедушка, потом все родители, потм все дети, потом все внуки и т.п.) \ No newline at end of file +**Обход в ширину** предполагает посещение всех узлов по уровням, начиная с корня (внутри уровня обход слева направо). +(аналогия: сначала дедушка, потом все родители, потом все дети, потом все внуки и т.п.) \ No newline at end of file From 476444eecf14a9481e1a1939626cf1b0b047300a Mon Sep 17 00:00:00 2001 From: love Date: Sat, 15 Mar 2025 18:08:07 +0000 Subject: [PATCH 04/34] README.md changes --- doc/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/README.md b/doc/README.md index db83b0e..32ca86a 100644 --- a/doc/README.md +++ b/doc/README.md @@ -48,9 +48,9 @@ 4 лекции. -- Определение дерева, дерева с корнем. Высота дерева, родительские, дочерние узлы, листья. Количество ребер. -- Обходы в глубину. pre-order, post-order и in-order для бинарных деревьев. -- Обход в ширину. +- [Определение дерева, дерева с корнем. Высота дерева, родительские, дочерние узлы, листья. Количество ребер.](topic3/question1-2-3.md) +- [Обходы в глубину. pre-order, post-order и in-order для бинарных деревьев.](topic3/question1-2-3.md) +- [Обход в ширину.](topic3/question1-2-3.md) - Дерево поиска. - Поиск ключа, вставка, удаление. - Необходимость балансировки. Три типа самобалансирующихся деревьев. From c8bb5ea099970ade56b5b82a86470fe26161625a Mon Sep 17 00:00:00 2001 From: love Date: Sat, 15 Mar 2025 19:33:38 +0000 Subject: [PATCH 05/34] question4-5-6.md theory --- doc/topic3/question1-2-3.md | 7 +++-- doc/topic3/question4-5-6.md | 56 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 doc/topic3/question4-5-6.md diff --git a/doc/topic3/question1-2-3.md b/doc/topic3/question1-2-3.md index 8a1fb09..ee0e86a 100644 --- a/doc/topic3/question1-2-3.md +++ b/doc/topic3/question1-2-3.md @@ -2,9 +2,10 @@ **Дерево** - структура данных, представляющая набор вершин (узлов), соединенных ребрами. -- *Родительский узел* - который имеет *дочерние узлы*. -- Самый "верхний" узел дерева (не имеющий родительских) называется *корнем (root)* +- Узлы содержат данные и некоторые указатели на *дочерние узлы*. +- *Родительский узел* - который имеет дочерние узлы. - Каждый узел (кроме корня) имеет ровно одного родителя. Узлы без потомков называются *листьями*. +- Самый "верхний" узел дерева (не имеющий родительских) называется *корнем (root)* - *Высота* дерева - длина самого длинного пути от корня до листа (число ребер между нимиб например у дерева только из корня высота 0). - *Количество ребер* в дереве всегда равно количеству узлов -1 (условно можно привязать к каждому узлу единственное ребро, соединяющее его с родителем. У корня такого нет -> N-1) @@ -66,7 +67,7 @@ def foreach(root): print(root.value) foreach(root.right) ``` - +> Это самый приятный вариант для дерева поиска, т.к. выводит значения вершин по порядку. --- ## **Обход в ширину (Breadth-First Search, BFS)** diff --git a/doc/topic3/question4-5-6.md b/doc/topic3/question4-5-6.md new file mode 100644 index 0000000..6bf720b --- /dev/null +++ b/doc/topic3/question4-5-6.md @@ -0,0 +1,56 @@ +# **Дерево поиска (Binary Search Tree, BST)** + +**Бинарное дерево поиска** - бинарное дерево, для которого выполняются дополнительные условия: + +- данные (data) обладают ключом (key), на котором определены операции сравнения. В конкретных реализациях это может быть пара (key, value) — (ключ, значение). +- все ключи в левом поддереве меньше ключа родителя +- все ключи в правом поддереве больше ключа родителя +- оба поддерева также являются бинарными поддеревьями поиска + +> (рассматриваем вариант с отсутствием равных элементов) + +Возможные операции: + +- вставка ключа +- поиск ключа +- удаление ключа + +--- + +# **Поиск ключа, вставка, удаление.** + +### **Поиск ключа** + +- начинаем с корня +- если дерево пусто (дошли до листа), сообщаем, что ключ не найден и останавливаемся +- если ключ равен текущему узлу, возвращаем его +- если ключ меньше ключа текущего узла, рекурсивно ищем его в левом поддереве +- если ключ больше --//-- в правом поддереве + +### **Вставка** + +- находим место до вставки (лист, к которому и в какую ветку присоединить ключ) по правилам поиска +- создаем новый узел в найденном месте + +### **Удаление ключа** + +- если узел - лист, просто удаляем его +- если у узла только одно дочернее поддерево, заменяем удаляемый узел на соответствующий дочерний +- если у узла два дочерних поддерева, находим максимальный узел левого поддерева или минимальный узел правого поддерева, заменяем удаляемый узел на этот, найденный узел из поддерева удаляем рекурсивно (у него могло быть правое дочернее поддерево) + +> пояснение: все ключи в левом поддереве меньше родителя -> меньше всех ключей в правом поддереве. самый правый ключ в левом поддереве больше всех остальных в нем -> можем вставить его вместо родителя, не нарушая правил + +--- +# **Необходимость балансировки. Три типа самобалансирующихся деревьев.** + +> Сложность поиска ключа в бинарном дереве поиска - О(h), где h - высота дерева. Поэтому более эффективны с точки зрения выполнения операций деревья с *балансировкой*, направленной на приближение размеров левых и правых поддеревьев у каждого родителя, а вследствие уменьшение общей h -> сложность приходит к О(log n). + +**Самобалансирующиеся деревья** - деревья, которые автоматически поддерживают свою сбалансированность после операций вставки и удаления. + +Основные типы: + +- **_AVL-дерево_** (разница высот левого и правого поддеревьев не превышает 1) +- **_красно-черное дерево_** (балансируется количеством черных узлов и правилом отсутствия красных потомков у красных родителей) +- **_декартово дерево_** (*treap* - от слов tree, heap) - гибридная структура данных со свойствами бинарного дерева и бинарной кучи (балансируется за счет случайного выбора *приоритетов*) +- *Splay-дерево* (splay - разворот) (перемещает недавно использованные элементы ближе к корню -> часто применяемые элементы находятся быстрее, но балансировка нестрогая) + From 8a93757b2b6e675d3db9a13d4f79213993a54def Mon Sep 17 00:00:00 2001 From: love Date: Sat, 15 Mar 2025 19:36:22 +0000 Subject: [PATCH 06/34] question4-5-6.md better --- doc/topic3/question4-5-6.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/topic3/question4-5-6.md b/doc/topic3/question4-5-6.md index 6bf720b..6dbc1f5 100644 --- a/doc/topic3/question4-5-6.md +++ b/doc/topic3/question4-5-6.md @@ -9,7 +9,7 @@ > (рассматриваем вариант с отсутствием равных элементов) -Возможные операции: +**Возможные операции:** - вставка ключа - поиск ключа @@ -43,11 +43,11 @@ --- # **Необходимость балансировки. Три типа самобалансирующихся деревьев.** -> Сложность поиска ключа в бинарном дереве поиска - О(h), где h - высота дерева. Поэтому более эффективны с точки зрения выполнения операций деревья с *балансировкой*, направленной на приближение размеров левых и правых поддеревьев у каждого родителя, а вследствие уменьшение общей h -> сложность приходит к О(log n). +Сложность поиска ключа в бинарном дереве поиска - **О(h)**, где h - высота дерева. Поэтому более эффективны с точки зрения выполнения операций деревья с *балансировкой*, направленной на приближение размеров левых и правых поддеревьев у каждого родителя, а вследствие уменьшение общей h -> сложность приходит к **О(log n)**. **Самобалансирующиеся деревья** - деревья, которые автоматически поддерживают свою сбалансированность после операций вставки и удаления. -Основные типы: +**Основные типы**: - **_AVL-дерево_** (разница высот левого и правого поддеревьев не превышает 1) - **_красно-черное дерево_** (балансируется количеством черных узлов и правилом отсутствия красных потомков у красных родителей) From 4a7367690dd096b1686768307aa6e9e1b93b9199 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 15 Mar 2025 19:37:56 +0000 Subject: [PATCH 07/34] README.md changes --- doc/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/README.md b/doc/README.md index 32ca86a..1810a6a 100644 --- a/doc/README.md +++ b/doc/README.md @@ -51,9 +51,9 @@ - [Определение дерева, дерева с корнем. Высота дерева, родительские, дочерние узлы, листья. Количество ребер.](topic3/question1-2-3.md) - [Обходы в глубину. pre-order, post-order и in-order для бинарных деревьев.](topic3/question1-2-3.md) - [Обход в ширину.](topic3/question1-2-3.md) -- Дерево поиска. -- Поиск ключа, вставка, удаление. -- Необходимость балансировки. Три типа самобалансирующихся деревьев. +- [Дерево поиска.](topic3/question4-5-6.md) +- [Поиск ключа, вставка, удаление.](topic3/question4-5-6.md) +- [Необходимость балансировки. Три типа самобалансирующихся деревьев.](topic3/question4-5-6.md) - Декартово дерево. Оценка средней высоты декартового дерева при случайных приоритетах (без доказательства). - Построение за O(n), если ключи упорядочены. - Основные операции над декартовым деревом. From 165d1f5c890f2a44a6652808aafb361700ea6ec5 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 15 Mar 2025 20:03:14 +0000 Subject: [PATCH 08/34] question1-2-3.md and question4-5-6.md theory --- doc/README.md | 2 +- doc/topic3/question1-2-3.md | 6 +++--- doc/topic3/question4-5-6.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/README.md b/doc/README.md index 1810a6a..e0e7c54 100644 --- a/doc/README.md +++ b/doc/README.md @@ -49,7 +49,7 @@ 4 лекции. - [Определение дерева, дерева с корнем. Высота дерева, родительские, дочерние узлы, листья. Количество ребер.](topic3/question1-2-3.md) -- [Обходы в глубину. pre-order, post-order и in-order для бинарных деревьев.](topic3/question1-2-3.md) +- [Обходы в глубину. Pre-order, post-order и in-order для бинарных деревьев.](topic3/question1-2-3.md) - [Обход в ширину.](topic3/question1-2-3.md) - [Дерево поиска.](topic3/question4-5-6.md) - [Поиск ключа, вставка, удаление.](topic3/question4-5-6.md) diff --git a/doc/topic3/question1-2-3.md b/doc/topic3/question1-2-3.md index ee0e86a..44c6679 100644 --- a/doc/topic3/question1-2-3.md +++ b/doc/topic3/question1-2-3.md @@ -5,9 +5,9 @@ - Узлы содержат данные и некоторые указатели на *дочерние узлы*. - *Родительский узел* - который имеет дочерние узлы. - Каждый узел (кроме корня) имеет ровно одного родителя. Узлы без потомков называются *листьями*. -- Самый "верхний" узел дерева (не имеющий родительских) называется *корнем (root)* +- Самый "верхний" узел дерева (не имеющий родительских) называется *корнем (root)*. - *Высота* дерева - длина самого длинного пути от корня до листа (число ребер между нимиб например у дерева только из корня высота 0). -- *Количество ребер* в дереве всегда равно количеству узлов -1 (условно можно привязать к каждому узлу единственное ребро, соединяющее его с родителем. У корня такого нет -> N-1) +- *Количество ребер* в дереве всегда равно количеству узлов -1 (условно можно привязать к каждому узлу единственное ребро, соединяющее его с родителем. У корня такого нет -> N-1). --- @@ -67,7 +67,7 @@ def foreach(root): print(root.value) foreach(root.right) ``` -> Это самый приятный вариант для дерева поиска, т.к. выводит значения вершин по порядку. +> Это самый приятный вариант для дерева поиска, т.к. выводит ключи вершин по возрастанию. --- ## **Обход в ширину (Breadth-First Search, BFS)** diff --git a/doc/topic3/question4-5-6.md b/doc/topic3/question4-5-6.md index 6dbc1f5..8f40e84 100644 --- a/doc/topic3/question4-5-6.md +++ b/doc/topic3/question4-5-6.md @@ -1,4 +1,4 @@ -# **Дерево поиска (Binary Search Tree, BST)** +# **Дерево поиска (Binary Search Tree, BST).** **Бинарное дерево поиска** - бинарное дерево, для которого выполняются дополнительные условия: From e78dc8ddbddd9492b75eac4c336f47b9da3119a6 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 15 Mar 2025 20:49:55 +0000 Subject: [PATCH 09/34] quick_sort? --- task_03/src/days_before_hot.cpp | 2 +- task_03/src/days_before_hot.h | 2 +- task_03/src/days_before_hot.hpp | 5 ++++ task_03/src/main.cpp | 5 ---- task_03/src/test.cpp | 12 ++++----- task_05/src/quick_sort.cpp | 44 +++++++++++++++++++++++++++++++++ task_05/src/quick_sort.hpp | 9 +++++++ 7 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 task_03/src/days_before_hot.hpp create mode 100644 task_05/src/quick_sort.cpp create mode 100644 task_05/src/quick_sort.hpp diff --git a/task_03/src/days_before_hot.cpp b/task_03/src/days_before_hot.cpp index 9c4556d..fe0f47b 100644 --- a/task_03/src/days_before_hot.cpp +++ b/task_03/src/days_before_hot.cpp @@ -1,6 +1,6 @@ #include "days_before_hot.h" -std::vector days_before_hot(std::vector temperatures) { +std::vector DaysBeforeHot(std::vector temperatures) { std::vector days_before_h(temperatures.size()); std::stack> memory{}; int size = temperatures.size() - 1; diff --git a/task_03/src/days_before_hot.h b/task_03/src/days_before_hot.h index 1ed1516..1fe89d6 100644 --- a/task_03/src/days_before_hot.h +++ b/task_03/src/days_before_hot.h @@ -2,4 +2,4 @@ #include #include -std::vector days_before_hot(std::vector temperatures); \ No newline at end of file +std::vector DaysBeforeHot(std::vector temperatures); \ No newline at end of file diff --git a/task_03/src/days_before_hot.hpp b/task_03/src/days_before_hot.hpp new file mode 100644 index 0000000..1fe89d6 --- /dev/null +++ b/task_03/src/days_before_hot.hpp @@ -0,0 +1,5 @@ +#include +#include +#include + +std::vector DaysBeforeHot(std::vector temperatures); \ No newline at end of file diff --git a/task_03/src/main.cpp b/task_03/src/main.cpp index 15f940d..5084ebd 100644 --- a/task_03/src/main.cpp +++ b/task_03/src/main.cpp @@ -5,9 +5,4 @@ #include "days_before_hot.h" int main() { - // std::vector temp{5, 7, 5, 3, 10, 0, 2, -1, 3}; - // std::vector ans{days_before_hot(temp)}; - // for (auto day : ans) { - // std::cout << day << std::endl; - // } } diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index a87e765..62277aa 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -6,35 +6,35 @@ TEST(first_test, ints) { std::vector temp{5, 7, 5, 3, 10, 0, 2, -1, 3}; std::vector ans{1, 3, 2, 1, 0, 1, 2, 1, 0}; - ASSERT_EQ(days_before_hot(temp), ans); + ASSERT_EQ(DaysBeforeHot(temp), ans); } TEST(second_test, doubles) { std::vector temp{5.1, 7.656, 5.0, 3, 10, -729.3, 2, -1.4, 3.2}; std::vector ans{1, 3, 2, 1, 0, 1, 2, 1, 0}; - ASSERT_EQ(days_before_hot(temp), ans); + ASSERT_EQ(DaysBeforeHot(temp), ans); } TEST(third_test, no_hot) { std::vector temp{5, 4.7, 4.3, 3, 2, 1.3}; std::vector ans{0, 0, 0, 0, 0, 0}; - ASSERT_EQ(days_before_hot(temp), ans); + ASSERT_EQ(DaysBeforeHot(temp), ans); } TEST(fourth_test, four) { std::vector temp{5, 4, 3, 2, 1, 10}; std::vector ans{5, 4, 3, 2, 1, 0}; - ASSERT_EQ(days_before_hot(temp), ans); + ASSERT_EQ(DaysBeforeHot(temp), ans); } TEST(fifth_test, one_number) { std::vector temp{1}; std::vector ans{0}; - ASSERT_EQ(days_before_hot(temp), ans); + ASSERT_EQ(DaysBeforeHot(temp), ans); } TEST(sixth_test, same_values) { std::vector temp{1, 1, 2, 2, 5, 1, 7}; std::vector ans{2, 1, 2, 1, 2, 1, 0}; - ASSERT_EQ(days_before_hot(temp), ans); + ASSERT_EQ(DaysBeforeHot(temp), ans); } \ No newline at end of file diff --git a/task_05/src/quick_sort.cpp b/task_05/src/quick_sort.cpp new file mode 100644 index 0000000..8b8b759 --- /dev/null +++ b/task_05/src/quick_sort.cpp @@ -0,0 +1,44 @@ +#include "quick_sort.hpp" + +std::vector Smaller (double elem, std::vector input){ + std::vector smaller{}; + for(auto i: input){ + if( i < elem){ + smaller.push_back(i); + } + } + return smaller; +} + +std::vector Bigger (double elem, std::vector input){ + std::vector bigger{}; + for(auto i: input){ + if( i > elem){ + bigger.push_back(i); + } + } + return bigger; +} + +std::vector Eq (double elem, std::vector input){ + std::vector eq{}; + for(auto i: input){ + if( i == elem){ + eq.push_back(i); + } + } + return eq; +} + +std::vector QuickSort (std::vector input){ + if(input.size() <= 1){ + return input; + } + double elem = input[0]; + std::vector eq{Eq(elem, input)}; + std::vector bigger {QuickSort(Bigger(elem, input))}; + std::vector ans {QuickSort(Smaller(elem, input))}; + ans.insert(ans.end(), eq.begin(), eq.end()); + ans.insert(ans.end(), bigger.begin(), bigger.end()); + return ans; +} \ No newline at end of file diff --git a/task_05/src/quick_sort.hpp b/task_05/src/quick_sort.hpp new file mode 100644 index 0000000..8a4e4a4 --- /dev/null +++ b/task_05/src/quick_sort.hpp @@ -0,0 +1,9 @@ +#include + +std::vector Smaller (double elem, std::vector input); + +std::vector Bigger (double elem, std::vector input); + +std::vector Eq (double elem, std::vector input); + +std::vector QuickSort (std::vector input); \ No newline at end of file From 9aa106b1e0b432ae240df1a321d7cdcc51d037e5 Mon Sep 17 00:00:00 2001 From: love Date: Mon, 17 Mar 2025 14:22:05 +0000 Subject: [PATCH 10/34] tests for stack and fix stack --- task_02/src/main.cpp | 16 +++++++++++- task_02/src/stack.cpp | 58 ------------------------------------------- task_02/src/stack.hpp | 13 +++++++++- task_02/src/test.cpp | 53 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 60 deletions(-) diff --git a/task_02/src/main.cpp b/task_02/src/main.cpp index 0e4393b..b5ca760 100644 --- a/task_02/src/main.cpp +++ b/task_02/src/main.cpp @@ -1,3 +1,17 @@ #include +#include -int main() { return 0; } +#include "stack.hpp" + +class NotTotallyOrdered { + int data; +}; + +int main() { + try { + MinStack stack{}; + stack.Pop(); + } catch (PopError s) { + std::cout << s.str << "\n"; + } +} diff --git a/task_02/src/stack.cpp b/task_02/src/stack.cpp index 8c75731..e69de29 100644 --- a/task_02/src/stack.cpp +++ b/task_02/src/stack.cpp @@ -1,58 +0,0 @@ -// #include "stack.hpp" - -// #include - -// template -// void Stack::Push(T value) { -// if (!head) { -// head = new Node; -// head->value = value; -// } else { -// Node* new_head = new Node; -// new_head->prev = head; -// new_head->value = value; -// head = new_head; -// } -// } - -// template -// T Stack::Pop() { -// T val = head->value; -// head = head->prev; -// return val; -// } - -// template -// requires(std::totally_ordered) -// void MinStack::Push(T value) { -// if (!head) { -// head = new Node; -// head->value = value; -// head_min = new Node; -// head_min->value = value; -// } else { -// Node* new_head = new Node; -// Node* new_head_min = new Node; -// new_head->prev = head; -// new_head->value = value; -// new_head_min->prev = head_min; -// new_head_min->value = std::min(head->value, value); -// head = new_head; -// head_min = new_head_min; -// } -// } - -// template -// requires(std::totally_ordered) -// T MinStack::Pop() { -// T val = head->value; -// head = head->prev; -// head_min = head_min->prev; -// return val; -// } - -// template -// requires(std::totally_ordered) -// T MinStack::GetMin() { -// return head_min->value; -// } \ No newline at end of file diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp index 0b77b4b..7c36e21 100644 --- a/task_02/src/stack.hpp +++ b/task_02/src/stack.hpp @@ -3,6 +3,10 @@ #include #include +struct PopError { + const char* str; +}; + template struct Node { T value; @@ -24,6 +28,7 @@ template requires(std::totally_ordered) class MinStack { public: + MinStack(){}; void Push(T value); T Pop(); T GetMin(); @@ -48,6 +53,9 @@ void Stack::Push(T value) { template T Stack::Pop() { + if (head == nullptr) { + throw PopError("Empty stack"); + } T val = head->value; head = head->prev; return val; @@ -67,7 +75,7 @@ void MinStack::Push(T value) { new_head->prev = head; new_head->value = value; new_head_min->prev = head_min; - new_head_min->value = std::min(head->value, value); + new_head_min->value = std::min(head_min->value, value); head = new_head; head_min = new_head_min; } @@ -76,6 +84,9 @@ void MinStack::Push(T value) { template requires(std::totally_ordered) T MinStack::Pop() { + if (head == nullptr) { + throw PopError("Empty stack"); + } T val = head->value; head = head->prev; head_min = head_min->prev; diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index f81ba58..4dc2a5b 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -1,6 +1,8 @@ #include +#include + #include "stack.hpp" TEST(StackTest, Simple) { @@ -37,4 +39,55 @@ TEST(MinStackTest, Simple) { ASSERT_EQ(stack.GetMin(), 1); ASSERT_EQ(stack.Pop(), 3); // Stack [1] ASSERT_EQ(stack.Pop(), 1); // Stack [] +} + +TEST(PopErrorTest, PopErrorTest) { + MinStack minstack{}; + ASSERT_THROW(minstack.Pop(), PopError); + Stack stack{}; + stack.Push(2); + stack.Pop(); + ASSERT_THROW(stack.Pop(), PopError); +} + +TEST(MinStackTest, Double) { + MinStack minstack{}; + minstack.Push(3.3); + ASSERT_EQ(minstack.GetMin(), 3.3); + minstack.Push(-0.7); + minstack.Push(4.8); + ASSERT_EQ(minstack.GetMin(), -0.7); + ASSERT_EQ(minstack.Pop(), 4.8); + ASSERT_EQ(minstack.GetMin(), -0.7); + ASSERT_EQ(minstack.Pop(), -0.7); + ASSERT_EQ(minstack.GetMin(), 3.3); +} + +TEST(MinStackTest, String) { // сравнивает алфавитно + MinStack minstack{}; + minstack.Push("bb"); + minstack.Push("r"); + ASSERT_EQ(minstack.GetMin(), "bb"); + minstack.Push("aaat"); + ASSERT_EQ(minstack.GetMin(), "aaat"); + ASSERT_EQ(minstack.Pop(), "aaat"); + ASSERT_EQ(minstack.GetMin(), "bb"); + ASSERT_EQ(minstack.Pop(), "r"); + ASSERT_EQ(minstack.Pop(), "bb"); +} + +TEST(MinStackTest, Vector) { // поэлементно + MinStack> minstack{}; + std::vector a{3, 2}; + minstack.Push(a); + std::vector b{5}; + minstack.Push(b); + ASSERT_EQ(minstack.GetMin(), a); + std::vector c{-4, 8, 9}; + minstack.Push(c); + ASSERT_EQ(minstack.GetMin(), c); + ASSERT_EQ(minstack.Pop(), c); + ASSERT_EQ(minstack.GetMin(), a); + ASSERT_EQ(minstack.Pop(), b); + ASSERT_EQ(minstack.Pop(), a); } \ No newline at end of file From 7b9f0f4bf17af278f90914210ef9345cb2955bb7 Mon Sep 17 00:00:00 2001 From: love Date: Mon, 17 Mar 2025 15:37:28 +0000 Subject: [PATCH 11/34] tests for quick_sort --- task_05/src/test.cpp | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/task_05/src/test.cpp b/task_05/src/test.cpp index 5e11617..cc7719b 100644 --- a/task_05/src/test.cpp +++ b/task_05/src/test.cpp @@ -1,6 +1,42 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include + +#include "quick_sort.hpp" + +TEST(QuickSort, Simple) { + std::vector vec{5.0, 6.3, 5.0, 1, -7.3, 3.3, 2.1, 2.1}; + std::vector ans{-7.3, 1, 2.1, 2.1, 3.3, 5, 5, 6.3}; + ASSERT_EQ(QuickSort(vec), ans); +} + +TEST(QuickSort, Simple2) { + std::vector vec{0.001, 0.008, 0.004, 0.006, 0.007, 0.007}; + std::vector ans{0.001, 0.004, 0.006, 0.007, 0.007, 0.008}; + ASSERT_EQ(QuickSort(vec), ans); +} + +TEST(QuickSort, Same) { + std::vector vec{4.2, 4.2, 4.2, 4.2, 4.2}; + std::vector ans{4.2, 4.2, 4.2, 4.2, 4.2}; + ASSERT_EQ(QuickSort(vec), ans); +} + +TEST(QuickSort, Already) { + std::vector vec{-2.2, -1.1, 0, 3.3}; + std::vector ans{-2.2, -1.1, 0, 3.3}; + ASSERT_EQ(QuickSort(vec), ans); +} + +TEST(QuickSort, Decrease) { + std::vector vec{9.9, 7.7, 5.5, 1.1, -0.7}; + std::vector ans{-0.7, 1.1, 5.5, 7.7, 9.9}; + ASSERT_EQ(QuickSort(vec), ans); +} + +TEST(QuickSort, Empty) { + std::vector vec{}; + std::vector ans{}; + ASSERT_EQ(QuickSort(vec), ans); } From 168a03b55f68dc9f1c387f0ebc4431a8ccda07f6 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 19 Apr 2025 20:01:06 +0000 Subject: [PATCH 12/34] tasks 2, 3, 5, 7 done --- task_02/src/main.cpp | 14 +-- task_02/src/test.cpp | 48 ++++---- task_03/src/days_before_hot.cpp | 2 +- task_03/src/days_before_hot.h | 5 - task_03/src/main | Bin 166760 -> 0 bytes task_03/src/main.cpp | 5 +- task_03/src/test.cpp | 2 +- task_05/src/quick_sort.cpp | 64 +++++----- task_07/src/avl_tree.cpp | 208 ++++++++++++++++++++++++++++++++ task_07/src/avl_tree.hpp | 101 ++++++++++++++++ task_07/src/print_tree.cpp | 35 ++++++ task_07/src/test.cpp | 68 ++++++++++- 12 files changed, 471 insertions(+), 81 deletions(-) delete mode 100644 task_03/src/days_before_hot.h delete mode 100755 task_03/src/main create mode 100644 task_07/src/avl_tree.cpp create mode 100644 task_07/src/avl_tree.hpp create mode 100644 task_07/src/print_tree.cpp diff --git a/task_02/src/main.cpp b/task_02/src/main.cpp index b5ca760..7601116 100644 --- a/task_02/src/main.cpp +++ b/task_02/src/main.cpp @@ -1,17 +1,5 @@ #include -#include #include "stack.hpp" -class NotTotallyOrdered { - int data; -}; - -int main() { - try { - MinStack stack{}; - stack.Pop(); - } catch (PopError s) { - std::cout << s.str << "\n"; - } -} +int main() {} \ No newline at end of file diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index 4dc2a5b..d4fe692 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -7,38 +7,38 @@ TEST(StackTest, Simple) { Stack stack{}; - stack.Push(1); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - stack.Push(3); // Stack [1, 3] - ASSERT_EQ(stack.Pop(), 3); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] + stack.Push(1); // [1] + ASSERT_EQ(stack.Pop(), 1); // [] + stack.Push(1); // [1] + stack.Push(2); // [1, 2] + ASSERT_EQ(stack.Pop(), 2); // [1] + ASSERT_EQ(stack.Pop(), 1); // [] + stack.Push(1); // [1] + stack.Push(2); // [1, 2] + ASSERT_EQ(stack.Pop(), 2); // [1] + stack.Push(3); // [1, 3] + ASSERT_EQ(stack.Pop(), 3); // [1] + ASSERT_EQ(stack.Pop(), 1); // [] } TEST(MinStackTest, Simple) { MinStack stack{}; - stack.Push(1); // Stack [1] + stack.Push(1); // [1] ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] + ASSERT_EQ(stack.Pop(), 1); // [] + stack.Push(1); // [1] + stack.Push(2); // [1, 2] ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] - stack.Push(1); // Stack [1] - stack.Push(2); // Stack [1, 2] + ASSERT_EQ(stack.Pop(), 2); // [1] + ASSERT_EQ(stack.Pop(), 1); // [] + stack.Push(1); // [1] + stack.Push(2); // [1, 2] ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 2); // Stack [1] - stack.Push(3); // Stack [1, 3] + ASSERT_EQ(stack.Pop(), 2); // [1] + stack.Push(3); // [1, 3] ASSERT_EQ(stack.GetMin(), 1); - ASSERT_EQ(stack.Pop(), 3); // Stack [1] - ASSERT_EQ(stack.Pop(), 1); // Stack [] + ASSERT_EQ(stack.Pop(), 3); // [1] + ASSERT_EQ(stack.Pop(), 1); // [] } TEST(PopErrorTest, PopErrorTest) { diff --git a/task_03/src/days_before_hot.cpp b/task_03/src/days_before_hot.cpp index fe0f47b..79ab601 100644 --- a/task_03/src/days_before_hot.cpp +++ b/task_03/src/days_before_hot.cpp @@ -1,4 +1,4 @@ -#include "days_before_hot.h" +#include "days_before_hot.hpp" std::vector DaysBeforeHot(std::vector temperatures) { std::vector days_before_h(temperatures.size()); diff --git a/task_03/src/days_before_hot.h b/task_03/src/days_before_hot.h deleted file mode 100644 index 1fe89d6..0000000 --- a/task_03/src/days_before_hot.h +++ /dev/null @@ -1,5 +0,0 @@ -#include -#include -#include - -std::vector DaysBeforeHot(std::vector temperatures); \ No newline at end of file diff --git a/task_03/src/main b/task_03/src/main deleted file mode 100755 index d74802a5f31c3c2e7d3ad399806043caa90ce0b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166760 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%0A3N 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 NcKzeY1<9Yq{{ // #include -#include "days_before_hot.h" +#include "days_before_hot.hpp" -int main() { -} +int main() {} diff --git a/task_03/src/test.cpp b/task_03/src/test.cpp index 62277aa..ae3eecc 100644 --- a/task_03/src/test.cpp +++ b/task_03/src/test.cpp @@ -1,7 +1,7 @@ #include -#include "days_before_hot.h" +#include "days_before_hot.hpp" TEST(first_test, ints) { std::vector temp{5, 7, 5, 3, 10, 0, 2, -1, 3}; diff --git a/task_05/src/quick_sort.cpp b/task_05/src/quick_sort.cpp index 8b8b759..e1a7a97 100644 --- a/task_05/src/quick_sort.cpp +++ b/task_05/src/quick_sort.cpp @@ -1,44 +1,44 @@ #include "quick_sort.hpp" -std::vector Smaller (double elem, std::vector input){ - std::vector smaller{}; - for(auto i: input){ - if( i < elem){ - smaller.push_back(i); - } +std::vector Smaller(double elem, std::vector input) { + std::vector smaller{}; + for (auto i : input) { + if (i < elem) { + smaller.push_back(i); } - return smaller; + } + return smaller; } -std::vector Bigger (double elem, std::vector input){ - std::vector bigger{}; - for(auto i: input){ - if( i > elem){ - bigger.push_back(i); - } +std::vector Bigger(double elem, std::vector input) { + std::vector bigger{}; + for (auto i : input) { + if (i > elem) { + bigger.push_back(i); } - return bigger; + } + return bigger; } -std::vector Eq (double elem, std::vector input){ - std::vector eq{}; - for(auto i: input){ - if( i == elem){ - eq.push_back(i); - } +std::vector Eq(double elem, std::vector input) { + std::vector eq{}; + for (auto i : input) { + if (i == elem) { + eq.push_back(i); } - return eq; + } + return eq; } -std::vector QuickSort (std::vector input){ - if(input.size() <= 1){ - return input; - } - double elem = input[0]; - std::vector eq{Eq(elem, input)}; - std::vector bigger {QuickSort(Bigger(elem, input))}; - std::vector ans {QuickSort(Smaller(elem, input))}; - ans.insert(ans.end(), eq.begin(), eq.end()); - ans.insert(ans.end(), bigger.begin(), bigger.end()); - return ans; +std::vector QuickSort(std::vector input) { + if (input.size() <= 1) { + return input; + } + double elem = input[0]; + std::vector eq{Eq(elem, input)}; + std::vector bigger{QuickSort(Bigger(elem, input))}; + std::vector ans{QuickSort(Smaller(elem, input))}; + ans.insert(ans.end(), eq.begin(), eq.end()); + ans.insert(ans.end(), bigger.begin(), bigger.end()); + return ans; } \ No newline at end of file diff --git a/task_07/src/avl_tree.cpp b/task_07/src/avl_tree.cpp new file mode 100644 index 0000000..bd8b344 --- /dev/null +++ b/task_07/src/avl_tree.cpp @@ -0,0 +1,208 @@ +#include "avl_tree.hpp" + +#include + +AvlTree::Node* AvlTree::Search(int search_key) const { + Node* cur = head; + while (cur != nullptr) { + if (cur->key == search_key) { + return cur; + } else if (search_key < cur->key) { + cur = cur->left_child; + } else if (search_key > cur->key) { + cur = cur->right_child; + } + } + return nullptr; +} + +void AvlTree::add(int new_key, int data) { + Node* new_node = new Node(new_key, data); + if (head == nullptr) { + head = new_node; + return; + } + Node* par = nullptr; + Node* cur = head; + + while (cur != nullptr) { + par = cur; + if (cur->key == new_key) { + std::cout << "the key is already exist" << "\n"; + delete new_node; + return; + } else if (new_key < cur->key) { + cur = cur->left_child; + } else if (new_key > cur->key) { + cur = cur->right_child; + } + } + + if (new_key < par->key) { + par->left_child = new_node; + } + if (new_key > par->key) { + par->right_child = new_node; + } + new_node->parent = par; + + while (new_node != nullptr) { + new_node = Balance(new_node)->parent; + } +} + +AvlTree::Node* AvlTree::SearchMin(Node* cur) const { + while (cur->left_child != nullptr) { + cur = cur->left_child; + } + return cur; +} + +void AvlTree::del(int del_key) { + Node* del_par = nullptr; + Node* del_node = head; + + while (del_node != nullptr) { + if (del_node->key == del_key) { + break; + } + del_par = del_node; + if (del_key < del_node->key) { + del_node = del_node->left_child; + } else if (del_key > del_node->key) { + del_node = del_node->right_child; + } + } + if (del_node == nullptr) { + return; + } + + Node* new_n; + + if (del_node->right_child == nullptr) { + new_n = del_node->left_child; + if (del_par == nullptr) { + head = del_node->left_child; + } else if (del_node == del_par->left_child) { + del_par->left_child = del_node->left_child; + } else { + del_par->right_child = del_node->left_child; + } + if (del_node->left_child != nullptr) { + del_node->left_child->parent = del_par; + } + delete del_node; + } else { + new_n = SearchMin(del_node->right_child); + if (new_n == del_node->right_child) { // это прямой правый ребенок + new_n->left_child = del_node->left_child; + } else { + new_n->parent->left_child = new_n->right_child; + if (new_n->right_child != nullptr) { + new_n->right_child->parent = new_n->parent; + } + new_n->right_child = del_node->right_child; + new_n->left_child = del_node->left_child; + del_node->right_child->parent = new_n; + } + new_n->parent = del_par; + if (del_node->left_child != nullptr) { + del_node->left_child->parent = new_n; + } + if (del_par != nullptr) { + if (del_node == del_par->left_child) { + del_par->left_child = new_n; + } else { + del_par->right_child = new_n; + } + } else { + head = new_n; + } + delete del_node; + } + Node* balancing = (new_n) ? new_n : del_par; + while (balancing != nullptr) { + balancing = Balance(balancing)->parent; + } +} + +AvlTree::AvlTree(std::vector> key_values) { + for (int i = 0; i < key_values.size(); ++i) { + add(key_values[i].first, key_values[i].second); + } +} + +AvlTree::Node* AvlTree::Balance(Node* old_par) { + UpdateHeight(old_par); + int diff{GetDifference(old_par)}; + if (diff > 1) { + if (GetDifference(old_par->left_child) > 0) { + return LeftLeftImbalance(old_par); + } else { + return LeftRightImbalance(old_par); + } + } else if (diff < -1) { + if (GetDifference(old_par->right_child) < 0) { + return RightRightImbalance(old_par); + } else { + return RightLeftImbalance(old_par); + } + } + return old_par; +} + +AvlTree::Node* AvlTree::LeftLeftImbalance(Node* old_par) { + Node* new_par{old_par->left_child}; + if (old_par->parent) { + if (old_par->parent->left_child == old_par) { + old_par->parent->left_child = new_par; + } else { + old_par->parent->right_child = new_par; + } + } + new_par->parent = old_par->parent; + old_par->left_child = new_par->right_child; + if (new_par->right_child) new_par->right_child->parent = old_par; + old_par->parent = new_par; + new_par->right_child = old_par; + UpdateHeight(old_par); + UpdateHeight(new_par); + if (old_par == head) { + head = new_par; + } + return new_par; +} + +AvlTree::Node* AvlTree::RightRightImbalance(Node* old_par) { + Node* new_par{old_par->right_child}; + if (old_par->parent) { + if (old_par->parent->right_child == old_par) { + old_par->parent->right_child = new_par; + } else { + old_par->parent->left_child = new_par; + } + } + new_par->parent = old_par->parent; + old_par->right_child = new_par->left_child; + if (new_par->left_child) new_par->left_child->parent = old_par; + old_par->parent = new_par; + new_par->left_child = old_par; + UpdateHeight(old_par); + UpdateHeight(new_par); + if (old_par == head) { + head = new_par; + } + return new_par; +} + +AvlTree::Node* AvlTree::LeftRightImbalance(Node* old_par) { + Node* new_par = RightRightImbalance(old_par->left_child); + new_par = LeftLeftImbalance(old_par); + return new_par; +} + +AvlTree::Node* AvlTree::RightLeftImbalance(Node* old_par) { + Node* new_par = LeftLeftImbalance(old_par->right_child); + new_par = RightRightImbalance(old_par); + return new_par; +} \ No newline at end of file diff --git a/task_07/src/avl_tree.hpp b/task_07/src/avl_tree.hpp new file mode 100644 index 0000000..0f08b3a --- /dev/null +++ b/task_07/src/avl_tree.hpp @@ -0,0 +1,101 @@ +#include +#include + +class AvlTree { + public: + AvlTree(){}; + AvlTree(std::vector> key_values); + int operator[](int key) { + Node* node{Search(key)}; + if (node == nullptr) { + throw std::out_of_range("dont exist"); + } else { + return node->data; + } + } + + void del(int del_key); + void add(int new_key, int data); + + private: + struct Node { + int key; + int data; + Node* parent = nullptr; + Node* left_child = nullptr; + Node* right_child = nullptr; + int height = 1; + Node(int key, int data) { + this->key = key; + this->data = data; + } + }; + Node* head = nullptr; + Node* Search(int key) const; + Node* SearchMin(Node* cur) const; + Node* SearchSuccessor(Node* cur) const; + + int GetHeight(Node* node) { + if (node) { + UpdateHeight(node); + return node->height; + } + return 0; + } + + int GetDifference(Node* node) { + if (node) { + return (GetHeight(node->left_child) - GetHeight(node->right_child)); + } + return 0; + } + + void UpdateHeight(Node* node) { + if (node) { + node->height = 1 + std::max(GetHeight(node->left_child), + GetHeight(node->right_child)); + } + } + + Node* Balance(Node* old_par); + Node* LeftLeftImbalance(Node* old_par); + Node* RightRightImbalance(Node* old_par); + Node* LeftRightImbalance(Node* old_par); + Node* RightLeftImbalance(Node* old_par); + + public: + friend std::ostream& operator<<(std::ostream& os, const AvlTree& tree); + class Iterator { + public: + Iterator(Node* node, const AvlTree& tree) + : current_node(node), tree(tree){}; + + std::pair operator*() const { + if (!current_node) { + throw std::out_of_range("dont exist"); + } + return {current_node->key, current_node->data}; + } + + Iterator& operator++() { + current_node = tree.SearchSuccessor(current_node); + return *this; + } + + bool operator==(const Iterator& other) const { + return current_node == other.current_node; + } + + bool operator!=(const Iterator& other) const { + return current_node != other.current_node; + } + + private: + Node* current_node; + const AvlTree& tree; + }; + Iterator begin() const { + return Iterator(head ? SearchMin(head) : nullptr, *this); + } + Iterator end() const { return Iterator(nullptr, *this); } +}; \ No newline at end of file diff --git a/task_07/src/print_tree.cpp b/task_07/src/print_tree.cpp new file mode 100644 index 0000000..310f2d9 --- /dev/null +++ b/task_07/src/print_tree.cpp @@ -0,0 +1,35 @@ +#include + +#include "avl_tree.hpp" + +std::ostream& operator<<(std::ostream& os, const AvlTree& tree) { + os << "{"; + bool first_elem = true; + for (const auto& [key, value] : tree) { + if (!first_elem) { + os << ", "; + } + os << "(" << key << ", " << value << ")"; + first_elem = false; + } + os << "}"; + return os; +} + +AvlTree::Node* AvlTree::SearchSuccessor(Node* cur) const { + if (cur == nullptr) { + return nullptr; + } + if (cur->right_child != nullptr) { + return SearchMin(cur->right_child); + } else { + Node* parent = cur->parent; + while (parent != nullptr && + cur == parent->right_child) { // пока я не левый ребенок или не + // корень в конце + cur = parent; + parent = parent->parent; + } + return parent; + } +} \ No newline at end of file diff --git a/task_07/src/test.cpp b/task_07/src/test.cpp index 5e11617..1ceda25 100644 --- a/task_07/src/test.cpp +++ b/task_07/src/test.cpp @@ -1,6 +1,70 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "avl_tree.hpp" + +TEST(AvlTest, Simple) { + std::vector> pairs{std::pair{5, 5}, + std::pair{3, 4}, + std::pair{9, 9}}; + AvlTree tree{pairs}; + ASSERT_EQ(tree[5], 5); + ASSERT_EQ(tree[3], 4); + ASSERT_EQ(tree[9], 9); + EXPECT_THROW({ int a{tree[2]}; }, std::out_of_range); +} + +TEST(AvlTest, AddDel) { + std::vector> pairs{std::pair{5, 5}, + std::pair{3, 4}, + std::pair{9, 9}}; + AvlTree tree{pairs}; + tree.add(7, 1); + ASSERT_EQ(tree[7], 1); + tree.del(5); + tree.del(3); + tree.add(3, 0); + ASSERT_EQ(tree[3], 0); + EXPECT_THROW({ int a{tree[5]}; }, std::out_of_range); +} + +TEST(AvlCoutTest, Simple) { + std::vector> pairs{std::pair{5, 5}, + std::pair{3, 4}, + std::pair{9, 9}}; + AvlTree tree{pairs}; + tree.add(7, 1); + + std::ostringstream oss; + oss << tree; + std::string expected = "{(3, 4), (5, 5), (7, 1), (9, 9)}"; + EXPECT_EQ(oss.str(), expected); } + +TEST(AvlCoutTest, Simple2) { + AvlTree tree; + tree.add(3, 30); + tree.add(1, 10); + tree.add(4, 40); + tree.add(2, 20); + + std::ostringstream oss; + oss << tree; + std::string expected = "{(1, 10), (2, 20), (3, 30), (4, 40)}"; + EXPECT_EQ(oss.str(), expected); +} + +TEST(AvlCoutTest, EmptyTreeOutput) { + AvlTree empty_tree; + std::ostringstream oss; + oss << empty_tree; + EXPECT_EQ(oss.str(), "{}"); +} + +TEST(AvlCoutTest, SingleElement) { + AvlTree tree; + tree.add(5, 6); + std::ostringstream oss; + oss << tree; + EXPECT_EQ(oss.str(), "{(5, 6)}"); +} \ No newline at end of file From 8e042f8c132aff53396fabc68ac551d56b5d2e29 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 26 Apr 2025 08:12:31 +0000 Subject: [PATCH 13/34] clang --- task_05/src/quick_sort.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/task_05/src/quick_sort.hpp b/task_05/src/quick_sort.hpp index 8a4e4a4..1a5f5d9 100644 --- a/task_05/src/quick_sort.hpp +++ b/task_05/src/quick_sort.hpp @@ -1,9 +1,9 @@ #include -std::vector Smaller (double elem, std::vector input); +std::vector Smaller(double elem, std::vector input); -std::vector Bigger (double elem, std::vector input); +std::vector Bigger(double elem, std::vector input); -std::vector Eq (double elem, std::vector input); +std::vector Eq(double elem, std::vector input); -std::vector QuickSort (std::vector input); \ No newline at end of file +std::vector QuickSort(std::vector input); \ No newline at end of file From 0b3f5e6e3f8329a4f4ce80d5a921f59097984a02 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 26 Apr 2025 08:27:41 +0000 Subject: [PATCH 14/34] camel --- task_07/src/avl_tree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/task_07/src/avl_tree.cpp b/task_07/src/avl_tree.cpp index bd8b344..d27477f 100644 --- a/task_07/src/avl_tree.cpp +++ b/task_07/src/avl_tree.cpp @@ -28,7 +28,7 @@ void AvlTree::add(int new_key, int data) { while (cur != nullptr) { par = cur; if (cur->key == new_key) { - std::cout << "the key is already exist" << "\n"; + std::cout << "the key is already exist\n"; delete new_node; return; } else if (new_key < cur->key) { From 2044a7543b185441b74a4fcfd2e51c1be21868c4 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 26 Apr 2025 08:57:49 +0000 Subject: [PATCH 15/34] clang --- task_07/src/avl_tree.cpp | 6 +++--- task_07/src/avl_tree.hpp | 4 ++-- task_07/src/test.cpp | 20 ++++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/task_07/src/avl_tree.cpp b/task_07/src/avl_tree.cpp index d27477f..cf4536f 100644 --- a/task_07/src/avl_tree.cpp +++ b/task_07/src/avl_tree.cpp @@ -16,7 +16,7 @@ AvlTree::Node* AvlTree::Search(int search_key) const { return nullptr; } -void AvlTree::add(int new_key, int data) { +void AvlTree::Add(int new_key, int data) { Node* new_node = new Node(new_key, data); if (head == nullptr) { head = new_node; @@ -58,7 +58,7 @@ AvlTree::Node* AvlTree::SearchMin(Node* cur) const { return cur; } -void AvlTree::del(int del_key) { +void AvlTree::Del(int del_key) { Node* del_par = nullptr; Node* del_node = head; @@ -128,7 +128,7 @@ void AvlTree::del(int del_key) { AvlTree::AvlTree(std::vector> key_values) { for (int i = 0; i < key_values.size(); ++i) { - add(key_values[i].first, key_values[i].second); + Add(key_values[i].first, key_values[i].second); } } diff --git a/task_07/src/avl_tree.hpp b/task_07/src/avl_tree.hpp index 0f08b3a..4495bab 100644 --- a/task_07/src/avl_tree.hpp +++ b/task_07/src/avl_tree.hpp @@ -14,8 +14,8 @@ class AvlTree { } } - void del(int del_key); - void add(int new_key, int data); + void Del(int del_key); + void Add(int new_key, int data); private: struct Node { diff --git a/task_07/src/test.cpp b/task_07/src/test.cpp index 1ceda25..2129e63 100644 --- a/task_07/src/test.cpp +++ b/task_07/src/test.cpp @@ -19,11 +19,11 @@ TEST(AvlTest, AddDel) { std::pair{3, 4}, std::pair{9, 9}}; AvlTree tree{pairs}; - tree.add(7, 1); + tree.Add(7, 1); ASSERT_EQ(tree[7], 1); - tree.del(5); - tree.del(3); - tree.add(3, 0); + tree.Del(5); + tree.Del(3); + tree.Add(3, 0); ASSERT_EQ(tree[3], 0); EXPECT_THROW({ int a{tree[5]}; }, std::out_of_range); } @@ -33,7 +33,7 @@ TEST(AvlCoutTest, Simple) { std::pair{3, 4}, std::pair{9, 9}}; AvlTree tree{pairs}; - tree.add(7, 1); + tree.Add(7, 1); std::ostringstream oss; oss << tree; @@ -43,10 +43,10 @@ TEST(AvlCoutTest, Simple) { TEST(AvlCoutTest, Simple2) { AvlTree tree; - tree.add(3, 30); - tree.add(1, 10); - tree.add(4, 40); - tree.add(2, 20); + tree.Add(3, 30); + tree.Add(1, 10); + tree.Add(4, 40); + tree.Add(2, 20); std::ostringstream oss; oss << tree; @@ -63,7 +63,7 @@ TEST(AvlCoutTest, EmptyTreeOutput) { TEST(AvlCoutTest, SingleElement) { AvlTree tree; - tree.add(5, 6); + tree.Add(5, 6); std::ostringstream oss; oss << tree; EXPECT_EQ(oss.str(), "{(5, 6)}"); From ff908829ec68b13f4be94231dc26712e43ff6cd2 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 3 May 2025 08:47:15 +0000 Subject: [PATCH 16/34] task_06 and changes in task_05 and utils --- lib/src/util.cpp | 30 +++++++++++++++++++++ lib/src/util.hpp | 7 +++++ task_05/src/quick_sort.cpp | 30 --------------------- task_05/src/quick_sort.hpp | 6 +---- task_06/src/main.cpp | 10 ++++++- task_06/src/search_statistic.cpp | 24 +++++++++++++++++ task_06/src/search_statistic.hpp | 3 +++ task_06/src/test.cpp | 45 ++++++++++++++++++++++++++++++-- task_07/src/avl_tree.hpp | 5 +--- 9 files changed, 118 insertions(+), 42 deletions(-) create mode 100644 task_06/src/search_statistic.cpp create mode 100644 task_06/src/search_statistic.hpp diff --git a/lib/src/util.cpp b/lib/src/util.cpp index 81e15bd..96cad30 100644 --- a/lib/src/util.cpp +++ b/lib/src/util.cpp @@ -1 +1,31 @@ #include "util.hpp" + +std::vector Smaller(double elem, std::vector input) { + std::vector smaller{}; + for (auto i : input) { + if (i < elem) { + smaller.push_back(i); + } + } + return smaller; +} + +std::vector Bigger(double elem, std::vector input) { + std::vector bigger{}; + for (auto i : input) { + if (i > elem) { + bigger.push_back(i); + } + } + return bigger; +} + +std::vector Eq(double elem, std::vector input) { + std::vector eq{}; + for (auto i : input) { + if (i == elem) { + eq.push_back(i); + } + } + return eq; +} \ No newline at end of file diff --git a/lib/src/util.hpp b/lib/src/util.hpp index e69de29..377cb16 100644 --- a/lib/src/util.hpp +++ b/lib/src/util.hpp @@ -0,0 +1,7 @@ +#include + +std::vector Smaller(double elem, std::vector input); + +std::vector Bigger(double elem, std::vector input); + +std::vector Eq(double elem, std::vector input); \ No newline at end of file diff --git a/task_05/src/quick_sort.cpp b/task_05/src/quick_sort.cpp index e1a7a97..7d1e139 100644 --- a/task_05/src/quick_sort.cpp +++ b/task_05/src/quick_sort.cpp @@ -1,35 +1,5 @@ #include "quick_sort.hpp" -std::vector Smaller(double elem, std::vector input) { - std::vector smaller{}; - for (auto i : input) { - if (i < elem) { - smaller.push_back(i); - } - } - return smaller; -} - -std::vector Bigger(double elem, std::vector input) { - std::vector bigger{}; - for (auto i : input) { - if (i > elem) { - bigger.push_back(i); - } - } - return bigger; -} - -std::vector Eq(double elem, std::vector input) { - std::vector eq{}; - for (auto i : input) { - if (i == elem) { - eq.push_back(i); - } - } - return eq; -} - std::vector QuickSort(std::vector input) { if (input.size() <= 1) { return input; diff --git a/task_05/src/quick_sort.hpp b/task_05/src/quick_sort.hpp index 1a5f5d9..8620c0f 100644 --- a/task_05/src/quick_sort.hpp +++ b/task_05/src/quick_sort.hpp @@ -1,9 +1,5 @@ #include -std::vector Smaller(double elem, std::vector input); - -std::vector Bigger(double elem, std::vector input); - -std::vector Eq(double elem, std::vector input); +#include "../../lib/src/util.hpp" std::vector QuickSort(std::vector input); \ No newline at end of file diff --git a/task_06/src/main.cpp b/task_06/src/main.cpp index 0e4393b..29b0399 100644 --- a/task_06/src/main.cpp +++ b/task_06/src/main.cpp @@ -1,3 +1,11 @@ #include -int main() { return 0; } +#include "search_statistic.hpp" + +int main() { + std::vector v = {5, 3, 1, 4, 2}; + std::cout << SearchNStatistics(v, 0) << std::endl; // 1 + std::cout << SearchNStatistics(v, 2) << std::endl; // 3 + std::cout << SearchNStatistics(v, 4) << std::endl; // 5 + return 0; +} diff --git a/task_06/src/search_statistic.cpp b/task_06/src/search_statistic.cpp new file mode 100644 index 0000000..77755a6 --- /dev/null +++ b/task_06/src/search_statistic.cpp @@ -0,0 +1,24 @@ +#include "search_statistic.hpp" + +#include + +double SearchNStatistics(std::vector input, int order) { + if (input.empty() or order >= input.size() or order < 0) { + throw std::invalid_argument("invalid data"); + } + double elem = input[0]; + std::vector smaller{Smaller(elem, input)}; + if (smaller.size() == order) { + return elem; + } else if (smaller.size() > order) { + return SearchNStatistics(smaller, order); + } + std::vector eq{Eq(elem, input)}; + order -= smaller.size(); + if (eq.size() > order) { + return elem; + } + order -= eq.size(); + std::vector bigger{Bigger(elem, input)}; + return SearchNStatistics(bigger, order); +} \ No newline at end of file diff --git a/task_06/src/search_statistic.hpp b/task_06/src/search_statistic.hpp new file mode 100644 index 0000000..5be40da --- /dev/null +++ b/task_06/src/search_statistic.hpp @@ -0,0 +1,3 @@ +#include "../../lib/src/util.hpp" + +double SearchNStatistics(std::vector input, int order); \ No newline at end of file diff --git a/task_06/src/test.cpp b/task_06/src/test.cpp index 5e11617..792ba97 100644 --- a/task_06/src/test.cpp +++ b/task_06/src/test.cpp @@ -1,6 +1,47 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "search_statistic.hpp" + +TEST(SearchNStatistics, Simple) { + std::vector v = {5, 3, 1, 4, 2}; + ASSERT_EQ(SearchNStatistics(v, 0), 1); + ASSERT_EQ(SearchNStatistics(v, 2), 3); + ASSERT_EQ(SearchNStatistics(v, 4), 5); +} + +TEST(SearchNStatistics, Same) { + std::vector v = {1, 1, 1, 1, 1, 3}; + ASSERT_EQ(SearchNStatistics(v, 2), 1); + ASSERT_EQ(SearchNStatistics(v, 0), 1); + ASSERT_EQ(SearchNStatistics(v, 5), 3); +} + +TEST(SearchNStatistics, Empty) { + std::vector v; + EXPECT_THROW(SearchNStatistics(v, 0), std::invalid_argument); +} + +TEST(SearchNStatistics, OrderException) { + std::vector v = {42.0}; + EXPECT_THROW(SearchNStatistics(v, 1), std::invalid_argument); +} + +TEST(SearchNStatistics, InvalidOrder) { + std::vector v = {42.0}; + EXPECT_THROW(SearchNStatistics(v, -3), std::invalid_argument); } + +TEST(SearchNStatistics, Sorted) { + std::vector v = {0, 1, 2, 3, 4, 5, 6, 7}; + EXPECT_EQ(SearchNStatistics(v, 0), 0); + EXPECT_EQ(SearchNStatistics(v, 3), 3); + EXPECT_EQ(SearchNStatistics(v, 6), 6); +} + +TEST(SearchNStatistics, NegativeNumbers) { + std::vector v = {-5, -1, -3, -2, -4}; + EXPECT_EQ(SearchNStatistics(v, 0), -5); + EXPECT_EQ(SearchNStatistics(v, 2), -3); + EXPECT_EQ(SearchNStatistics(v, 4), -1); +} \ No newline at end of file diff --git a/task_07/src/avl_tree.hpp b/task_07/src/avl_tree.hpp index 4495bab..ae19f69 100644 --- a/task_07/src/avl_tree.hpp +++ b/task_07/src/avl_tree.hpp @@ -25,10 +25,7 @@ class AvlTree { Node* left_child = nullptr; Node* right_child = nullptr; int height = 1; - Node(int key, int data) { - this->key = key; - this->data = data; - } + Node(int key, int data) : key(key), data(data) {} }; Node* head = nullptr; Node* Search(int key) const; From d2bae7d6edb54a1b714f9079afa5a25ea60c68d1 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 3 May 2025 08:48:40 +0000 Subject: [PATCH 17/34] clean --- task_06/src/main.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/task_06/src/main.cpp b/task_06/src/main.cpp index 29b0399..46aa64d 100644 --- a/task_06/src/main.cpp +++ b/task_06/src/main.cpp @@ -2,10 +2,4 @@ #include "search_statistic.hpp" -int main() { - std::vector v = {5, 3, 1, 4, 2}; - std::cout << SearchNStatistics(v, 0) << std::endl; // 1 - std::cout << SearchNStatistics(v, 2) << std::endl; // 3 - std::cout << SearchNStatistics(v, 4) << std::endl; // 5 - return 0; -} +int main() { return 0; } From f8bea2b0826ff9a686e4184373eed9d17bf0fc88 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 3 May 2025 08:55:53 +0000 Subject: [PATCH 18/34] some changes for clang-tidy --- lib/src/util.cpp | 6 +++--- lib/src/util.hpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/util.cpp b/lib/src/util.cpp index 96cad30..ed26906 100644 --- a/lib/src/util.cpp +++ b/lib/src/util.cpp @@ -1,6 +1,6 @@ #include "util.hpp" -std::vector Smaller(double elem, std::vector input) { +std::vector Smaller(double elem, const std::vector& input) { std::vector smaller{}; for (auto i : input) { if (i < elem) { @@ -10,7 +10,7 @@ std::vector Smaller(double elem, std::vector input) { return smaller; } -std::vector Bigger(double elem, std::vector input) { +std::vector Bigger(double elem, const std::vector& input) { std::vector bigger{}; for (auto i : input) { if (i > elem) { @@ -20,7 +20,7 @@ std::vector Bigger(double elem, std::vector input) { return bigger; } -std::vector Eq(double elem, std::vector input) { +std::vector Eq(double elem, const std::vector& input) { std::vector eq{}; for (auto i : input) { if (i == elem) { diff --git a/lib/src/util.hpp b/lib/src/util.hpp index 377cb16..f76a723 100644 --- a/lib/src/util.hpp +++ b/lib/src/util.hpp @@ -1,7 +1,7 @@ #include -std::vector Smaller(double elem, std::vector input); +std::vector Smaller(double elem, const std::vector& input); -std::vector Bigger(double elem, std::vector input); +std::vector Bigger(double elem, const std::vector& input); -std::vector Eq(double elem, std::vector input); \ No newline at end of file +std::vector Eq(double elem, const std::vector& input); \ No newline at end of file From 0fd87f97574eb735f4e3eda2bc9126eba410b7ec Mon Sep 17 00:00:00 2001 From: love Date: Sat, 3 May 2025 16:54:25 +0000 Subject: [PATCH 19/34] changes --- task_02/src/stack.cpp | 0 task_02/src/stack.hpp | 19 ++++++++++++++----- task_02/src/test.cpp | 10 +++++++--- task_03/src/days_before_hot.cpp | 21 +++++++++++---------- task_03/src/days_before_hot.hpp | 4 ++++ task_03/src/main.cpp | 3 --- task_03/src/topology_sort.cpp | 1 - task_03/src/topology_sort.hpp | 1 - task_06/src/search_statistic.cpp | 4 ++-- task_06/src/search_statistic.hpp | 2 +- 10 files changed, 39 insertions(+), 26 deletions(-) delete mode 100644 task_02/src/stack.cpp delete mode 100644 task_03/src/topology_sort.cpp delete mode 100644 task_03/src/topology_sort.hpp diff --git a/task_02/src/stack.cpp b/task_02/src/stack.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp index 7c36e21..f628f50 100644 --- a/task_02/src/stack.hpp +++ b/task_02/src/stack.hpp @@ -3,14 +3,14 @@ #include #include -struct PopError { - const char* str; +struct EmptyStackError : std::exception { + using std::exception::exception; }; template struct Node { T value; - Node* prev = nullptr; + Node* prev = nullptr; }; template @@ -54,10 +54,12 @@ void Stack::Push(T value) { template T Stack::Pop() { if (head == nullptr) { - throw PopError("Empty stack"); + throw EmptyStackError(); } + Node* del_node = head; T val = head->value; head = head->prev; + delete del_node; return val; } @@ -85,16 +87,23 @@ template requires(std::totally_ordered) T MinStack::Pop() { if (head == nullptr) { - throw PopError("Empty stack"); + throw EmptyStackError(); } + Node* del_node = head; + Node* del_node_min = head_min; T val = head->value; head = head->prev; head_min = head_min->prev; + delete del_node; + delete del_node_min; return val; } template requires(std::totally_ordered) T MinStack::GetMin() { + if (head_min == nullptr) { + throw EmptyStackError(); + } return head_min->value; } \ No newline at end of file diff --git a/task_02/src/test.cpp b/task_02/src/test.cpp index d4fe692..989d0ed 100644 --- a/task_02/src/test.cpp +++ b/task_02/src/test.cpp @@ -41,13 +41,17 @@ TEST(MinStackTest, Simple) { ASSERT_EQ(stack.Pop(), 1); // [] } -TEST(PopErrorTest, PopErrorTest) { +TEST(PopErrorTest, EmptyStackErrorTest) { MinStack minstack{}; - ASSERT_THROW(minstack.Pop(), PopError); + ASSERT_THROW(minstack.Pop(), EmptyStackError); + MinStack minstack2{}; + minstack2.Push(6); + minstack2.Pop(); + ASSERT_THROW(minstack2.GetMin(), EmptyStackError); Stack stack{}; stack.Push(2); stack.Pop(); - ASSERT_THROW(stack.Pop(), PopError); + ASSERT_THROW(stack.Pop(), EmptyStackError); } TEST(MinStackTest, Double) { diff --git a/task_03/src/days_before_hot.cpp b/task_03/src/days_before_hot.cpp index 79ab601..f53fd1b 100644 --- a/task_03/src/days_before_hot.cpp +++ b/task_03/src/days_before_hot.cpp @@ -1,20 +1,21 @@ #include "days_before_hot.hpp" std::vector DaysBeforeHot(std::vector temperatures) { - std::vector days_before_h(temperatures.size()); - std::stack> memory{}; + std::vector days_before_hot(temperatures.size()); + std::stack hotter_temperatures{}; int size = temperatures.size() - 1; for (int i{size}; i >= 0; --i) { - while (!(memory.empty()) and (memory.top()[0] <= temperatures[i])) { - memory.pop(); + while (!(hotter_temperatures.empty()) and + (hotter_temperatures.top().temperature <= temperatures[i])) { + hotter_temperatures.pop(); } - if (memory.empty()) { - days_before_h[i] = 0; + if (hotter_temperatures.empty()) { + days_before_hot[i] = 0; } else { - days_before_h[i] = memory.top()[1] - i; + days_before_hot[i] = hotter_temperatures.top().day_index - i; } - std::vector day{temperatures[i], static_cast(i)}; - memory.push(day); + TemperatureWithDayIndex day{temperatures[i], i}; + hotter_temperatures.push(day); } - return days_before_h; + return days_before_hot; } \ No newline at end of file diff --git a/task_03/src/days_before_hot.hpp b/task_03/src/days_before_hot.hpp index 1fe89d6..1b78a9e 100644 --- a/task_03/src/days_before_hot.hpp +++ b/task_03/src/days_before_hot.hpp @@ -2,4 +2,8 @@ #include #include +struct TemperatureWithDayIndex { + double temperature; + int day_index; +}; std::vector DaysBeforeHot(std::vector temperatures); \ No newline at end of file diff --git a/task_03/src/main.cpp b/task_03/src/main.cpp index b327c4c..8e89d61 100644 --- a/task_03/src/main.cpp +++ b/task_03/src/main.cpp @@ -1,6 +1,3 @@ -// #include -// #include -// #include #include "days_before_hot.hpp" diff --git a/task_03/src/topology_sort.cpp b/task_03/src/topology_sort.cpp deleted file mode 100644 index e53f670..0000000 --- a/task_03/src/topology_sort.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "topology_sort.hpp" diff --git a/task_03/src/topology_sort.hpp b/task_03/src/topology_sort.hpp deleted file mode 100644 index 6f70f09..0000000 --- a/task_03/src/topology_sort.hpp +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/task_06/src/search_statistic.cpp b/task_06/src/search_statistic.cpp index 77755a6..5de4ad4 100644 --- a/task_06/src/search_statistic.cpp +++ b/task_06/src/search_statistic.cpp @@ -2,8 +2,8 @@ #include -double SearchNStatistics(std::vector input, int order) { - if (input.empty() or order >= input.size() or order < 0) { +double SearchNStatistics(const std::vector& input, int order) { + if (input.empty() || order >= input.size() || order < 0) { throw std::invalid_argument("invalid data"); } double elem = input[0]; diff --git a/task_06/src/search_statistic.hpp b/task_06/src/search_statistic.hpp index 5be40da..ccb8453 100644 --- a/task_06/src/search_statistic.hpp +++ b/task_06/src/search_statistic.hpp @@ -1,3 +1,3 @@ #include "../../lib/src/util.hpp" -double SearchNStatistics(std::vector input, int order); \ No newline at end of file +double SearchNStatistics(const std::vector& input, int order); \ No newline at end of file From c2a3bdb09844b3584ac1519afff746a179ba4cbf Mon Sep 17 00:00:00 2001 From: love Date: Sat, 3 May 2025 17:04:25 +0000 Subject: [PATCH 20/34] changes --- task_03/src/days_before_hot.cpp | 3 +++ task_03/src/days_before_hot.hpp | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/task_03/src/days_before_hot.cpp b/task_03/src/days_before_hot.cpp index f53fd1b..71cfff3 100644 --- a/task_03/src/days_before_hot.cpp +++ b/task_03/src/days_before_hot.cpp @@ -1,5 +1,8 @@ #include "days_before_hot.hpp" +#include +#include + std::vector DaysBeforeHot(std::vector temperatures) { std::vector days_before_hot(temperatures.size()); std::stack hotter_temperatures{}; diff --git a/task_03/src/days_before_hot.hpp b/task_03/src/days_before_hot.hpp index 1b78a9e..e056090 100644 --- a/task_03/src/days_before_hot.hpp +++ b/task_03/src/days_before_hot.hpp @@ -1,5 +1,3 @@ -#include -#include #include struct TemperatureWithDayIndex { From 02902284c3d18cd7cdf9be18f422535844099bd9 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 3 May 2025 17:14:32 +0000 Subject: [PATCH 21/34] changes --- task_03/src/days_before_hot.cpp | 5 +---- task_03/src/days_before_hot.hpp | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/task_03/src/days_before_hot.cpp b/task_03/src/days_before_hot.cpp index 71cfff3..a75f943 100644 --- a/task_03/src/days_before_hot.cpp +++ b/task_03/src/days_before_hot.cpp @@ -1,14 +1,11 @@ #include "days_before_hot.hpp" -#include -#include - std::vector DaysBeforeHot(std::vector temperatures) { std::vector days_before_hot(temperatures.size()); std::stack hotter_temperatures{}; int size = temperatures.size() - 1; for (int i{size}; i >= 0; --i) { - while (!(hotter_temperatures.empty()) and + while (!(hotter_temperatures.empty()) && (hotter_temperatures.top().temperature <= temperatures[i])) { hotter_temperatures.pop(); } diff --git a/task_03/src/days_before_hot.hpp b/task_03/src/days_before_hot.hpp index e056090..287bd37 100644 --- a/task_03/src/days_before_hot.hpp +++ b/task_03/src/days_before_hot.hpp @@ -1,3 +1,4 @@ +#include #include struct TemperatureWithDayIndex { From 2157390c0dcb186f005124d85389f53702e6589b Mon Sep 17 00:00:00 2001 From: love Date: Sun, 4 May 2025 19:57:54 +0000 Subject: [PATCH 22/34] task_01 --- task_01/src/task.cpp | 22 ++++++++++++++++++++ task_01/src/task.hpp | 4 ++++ task_01/src/test.cpp | 49 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 task_01/src/task.cpp create mode 100644 task_01/src/task.hpp diff --git a/task_01/src/task.cpp b/task_01/src/task.cpp new file mode 100644 index 0000000..c7cdbd1 --- /dev/null +++ b/task_01/src/task.cpp @@ -0,0 +1,22 @@ +#include "task.hpp" + +#include + +std::pair search_numbers(int search_num, std::vector data) { + if (data.size() <= 1) { + throw std::invalid_argument("vector is too small"); + } + size_t bottom{0}; + size_t top{data.size() - 1}; + while (bottom != top) { + if (data[bottom] + data[top] == search_num) { + std::pair ans{data[bottom], data[top]}; + return ans; + } else if (data[bottom] + data[top] > search_num) { + --top; + } else { + ++bottom; + } + } + throw std::invalid_argument("no suitable pair"); +} \ No newline at end of file diff --git a/task_01/src/task.hpp b/task_01/src/task.hpp new file mode 100644 index 0000000..5a0c501 --- /dev/null +++ b/task_01/src/task.hpp @@ -0,0 +1,4 @@ +#include +#include + +std::pair search_numbers(int search_num, std::vector data); \ No newline at end of file diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index 87cef73..1d3356b 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -1,5 +1,48 @@ #include -TEST(Test, Simple) { - ASSERT_EQ(1, 1); // Stack [] -} \ No newline at end of file +#include "task.hpp" + +TEST(Task1, Simple) { + std::vector data{1, 3, 4, 4, 7, 11}; + std::pair ans{3, 7}; + ASSERT_EQ(search_numbers(10, data), ans); +} + +TEST(Task1, FirstAndLast) { + std::vector data{1, 2, 3, 4, 5, 99}; + std::pair ans{1, 99}; + ASSERT_EQ(search_numbers(100, data), ans); +} + +TEST(Task1, Negative) { + std::vector data{-5, -3, 0, 1, 2, 8}; + std::pair ans{-3, 8}; + ASSERT_EQ(search_numbers(5, data), ans); +} + +TEST(Task1, Simple2) { + std::vector data{10, 11, 12, 13, 14, 15}; + std::pair ans{10, 15}; + ASSERT_EQ(search_numbers(25, data), ans); +} + +TEST(Task1, SmallVector) { + std::vector data{1, 2}; + std::pair ans{1, 2}; + ASSERT_EQ(search_numbers(3, data), ans); +} + +TEST(Task1, NoPair) { + std::vector data{1, 2, 3, 4, 5}; + ASSERT_THROW(search_numbers(100, data), std::invalid_argument); +} + +TEST(Task1, Empty) { + std::vector data; + ASSERT_THROW(search_numbers(10, data), std::invalid_argument); +} + +TEST(Task1, SingleElementVector) { + std::vector data{5}; + ASSERT_THROW(search_numbers(5, data), std::invalid_argument); +} From 290f8d5f1fbf3247dde03442dcc9bcfafe266a2b Mon Sep 17 00:00:00 2001 From: love Date: Mon, 5 May 2025 16:35:57 +0000 Subject: [PATCH 23/34] task_08 hash_table --- task_08/src/hash_table.cpp | 93 ++++++++++++++++++++++++++++++++++++++ task_08/src/hash_table.hpp | 36 +++++++++++++++ task_08/src/main.cpp | 13 +++++- task_08/src/test.cpp | 72 ++++++++++++++++++++++++++++- 4 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 task_08/src/hash_table.cpp create mode 100644 task_08/src/hash_table.hpp diff --git a/task_08/src/hash_table.cpp b/task_08/src/hash_table.cpp new file mode 100644 index 0000000..82d411c --- /dev/null +++ b/task_08/src/hash_table.cpp @@ -0,0 +1,93 @@ +#include "hash_table.hpp" + +int HashTable::SecondHashFunc(std::string key) { return 1; } + +int HashTable::FirstHashFunc(std::string key) { return base_hasher(key); } + +int HashTable::HashFunc(std::string key, int iteration) { + return (FirstHashFunc(key) + iteration * SecondHashFunc(key)) % array.size(); +} + +HashTable::HashTable(size_t size) { + std::vector vec(size); + array = vec; +} + +HashTable::HashTable() { + std::vector vec(20); + array = vec; +} + +HashTable::HashTable(std::vector> input) { + std::vector vec(input.size() * 3); + array = vec; + for (auto elem : input) { + Add(elem.first, elem.second); + } +} + +int HashTable::FindIndex(std::string key) { + for (int i{0}; i < array.size(); ++i) { + int index{HashFunc(key, i)}; + if (array[index].condition == Condition::Empty) { + return -1; + } + if (array[index].condition == Condition::Full && array[index].key == key) { + return index; + } + } + return -1; +} + +void HashTable::Del(std::string del_key) { + int index = FindIndex(del_key); + if (index == -1) { + throw HashTableError("key do not exist"); + } + array[index].condition = Condition::Cleared; + full_elements -= 1; + return; +} + +int HashTable::Get(std::string key) { + int index = FindIndex(key); + if (index == -1) { + throw HashTableError("key do not exist"); + } + return array[index].value; +} + +void HashTable::Add(std::string new_key, int new_value) { + int index = FindIndex(new_key); + if (index != -1) { + array[index].value = new_value; + return; + } + for (int i{0}; i < array.size(); ++i) { + index = HashFunc(new_key, i); + if (array[index].condition == Condition::Empty || + array[index].condition == Condition::Cleared) { + array[index].key = new_key; + array[index].value = new_value; + array[index].condition = Condition::Full; + full_elements += 1; + if (full_elements > array.size() / 2) { + UpdateArray(); + } + return; + } + } + throw HashTableError("full table"); +} + +void HashTable::UpdateArray() { + std::vector old_array = std::move(array); + std::vector new_array(old_array.size() * 2); + array = new_array; + full_elements = 0; + for (auto elem : old_array) { + if (elem.condition == Condition::Full) { + Add(elem.key, elem.value); + } + } +} \ No newline at end of file diff --git a/task_08/src/hash_table.hpp b/task_08/src/hash_table.hpp new file mode 100644 index 0000000..e926222 --- /dev/null +++ b/task_08/src/hash_table.hpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include + +struct HashTableError : std::runtime_error { + using std::runtime_error::runtime_error; +}; +enum class Condition { Empty, Full, Cleared }; + +struct HashTable { + public: + HashTable(); + HashTable(size_t size); + HashTable(std::vector> input); + void Add(std::string new_key, int new_value); + void Del(std::string del_key); + int Get(std::string key); + + private: + struct Element { + public: + Condition condition = Condition::Empty; + std::string key; + int value; + }; + std::vector array; + std::hash base_hasher; + int full_elements = 0; + void UpdateArray(); + int FindIndex(std::string key); // находит, если существует + // если нет такого, возвращает -1 + int FirstHashFunc(std::string num); + int SecondHashFunc(std::string num); + int HashFunc(std::string num, int iteration); +}; \ No newline at end of file diff --git a/task_08/src/main.cpp b/task_08/src/main.cpp index 0e4393b..80c1646 100644 --- a/task_08/src/main.cpp +++ b/task_08/src/main.cpp @@ -1,3 +1,14 @@ #include -int main() { return 0; } +#include "hash_table.hpp" + +int main() { + HashTable hash_table(2); + hash_table.Add("a", 4); + hash_table.Add("b", 1); + hash_table.Add("c", 6); + int val = hash_table.Get("b"); + std::cout << val << "\n"; + HashTable h(-2); + return 0; +} diff --git a/task_08/src/test.cpp b/task_08/src/test.cpp index 5e11617..9cdc7ec 100644 --- a/task_08/src/test.cpp +++ b/task_08/src/test.cpp @@ -1,6 +1,74 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "hash_table.hpp" + +TEST(HashTableTest, Simple) { + HashTable hash_table; + hash_table.Add("f", 5); + hash_table.Add("a", -1); + hash_table.Add("b", 4); + ASSERT_EQ(hash_table.Get("b"), 4); + ASSERT_EQ(hash_table.Get("b"), 4); + ASSERT_EQ(hash_table.Get("a"), -1); + ASSERT_EQ(hash_table.Get("f"), 5); +} + +TEST(HashTableTest, ExceptionLen) { + ASSERT_THROW(HashTable hash_table(-1), std::length_error); +} + +TEST(HashTableTest, ExceptionGet) { + HashTable hash_table; + hash_table.Add("f", 5); + ASSERT_THROW(hash_table.Get("ff"), HashTableError); + hash_table.Add("qw", 8); + ASSERT_EQ(hash_table.Get("f"), 5); + hash_table.Del("f"); + ASSERT_THROW(hash_table.Get("f"), HashTableError); +} + +TEST(HashTableTest, ExceptionDel) { + HashTable hash_table; + hash_table.Add("f", 5); + ASSERT_THROW(hash_table.Del("ff"), HashTableError); +} + +TEST(HashTableTest, ChangeValue) { + HashTable hash_table; + hash_table.Add("42", 42); + ASSERT_EQ(hash_table.Get("42"), 42); + hash_table.Add("42", -42); + ASSERT_EQ(hash_table.Get("42"), -42); +} + +TEST(HashTableTest, RehashingWorks) { + HashTable hash_table(1); + hash_table.Add("one", 1); + hash_table.Add("two", 2); + hash_table.Add("three", 3); + hash_table.Add("four", 4); + + ASSERT_EQ(hash_table.Get("one"), 1); + ASSERT_EQ(hash_table.Get("two"), 2); + ASSERT_EQ(hash_table.Get("three"), 3); + ASSERT_EQ(hash_table.Get("four"), 4); } + +TEST(HashTableTest, ConstructorVector) { + std::vector> data = { + {"a", 1}, {"b", 2}, {"c", 3}}; + HashTable hash_table(data); + + ASSERT_EQ(hash_table.Get("a"), 1); + ASSERT_EQ(hash_table.Get("b"), 2); + ASSERT_EQ(hash_table.Get("c"), 3); +} + +TEST(HashTableTest, AddAfterDel) { + HashTable hash_table; + hash_table.Add("d", 13); + hash_table.Del("d"); + hash_table.Add("d", 0); + ASSERT_EQ(hash_table.Get("d"), 0); +} \ No newline at end of file From 4a19ead3c0167c01f64261477ed39ee72c942b86 Mon Sep 17 00:00:00 2001 From: love Date: Mon, 5 May 2025 17:32:30 +0000 Subject: [PATCH 24/34] for clang-tidy --- task_08/src/hash_table.cpp | 10 +++++----- task_08/src/hash_table.hpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/task_08/src/hash_table.cpp b/task_08/src/hash_table.cpp index 82d411c..7a3f34d 100644 --- a/task_08/src/hash_table.cpp +++ b/task_08/src/hash_table.cpp @@ -26,7 +26,7 @@ HashTable::HashTable(std::vector> input) { } } -int HashTable::FindIndex(std::string key) { +int HashTable::FindIndex(const std::string& key) { for (int i{0}; i < array.size(); ++i) { int index{HashFunc(key, i)}; if (array[index].condition == Condition::Empty) { @@ -39,7 +39,7 @@ int HashTable::FindIndex(std::string key) { return -1; } -void HashTable::Del(std::string del_key) { +void HashTable::Del(const std::string& del_key) { int index = FindIndex(del_key); if (index == -1) { throw HashTableError("key do not exist"); @@ -49,7 +49,7 @@ void HashTable::Del(std::string del_key) { return; } -int HashTable::Get(std::string key) { +int HashTable::Get(const std::string& key) { int index = FindIndex(key); if (index == -1) { throw HashTableError("key do not exist"); @@ -57,7 +57,7 @@ int HashTable::Get(std::string key) { return array[index].value; } -void HashTable::Add(std::string new_key, int new_value) { +void HashTable::Add(const std::string& new_key, int new_value) { int index = FindIndex(new_key); if (index != -1) { array[index].value = new_value; @@ -85,7 +85,7 @@ void HashTable::UpdateArray() { std::vector new_array(old_array.size() * 2); array = new_array; full_elements = 0; - for (auto elem : old_array) { + for (const auto& elem : old_array) { if (elem.condition == Condition::Full) { Add(elem.key, elem.value); } diff --git a/task_08/src/hash_table.hpp b/task_08/src/hash_table.hpp index e926222..7d7808c 100644 --- a/task_08/src/hash_table.hpp +++ b/task_08/src/hash_table.hpp @@ -13,9 +13,9 @@ struct HashTable { HashTable(); HashTable(size_t size); HashTable(std::vector> input); - void Add(std::string new_key, int new_value); - void Del(std::string del_key); - int Get(std::string key); + void Add(const std::string& new_key, int new_value); + void Del(const std::string& del_key); + int Get(const std::string& key); private: struct Element { @@ -28,8 +28,8 @@ struct HashTable { std::hash base_hasher; int full_elements = 0; void UpdateArray(); - int FindIndex(std::string key); // находит, если существует - // если нет такого, возвращает -1 + int FindIndex(const std::string& key); // находит, если существует + // если нет такого, возвращает -1 int FirstHashFunc(std::string num); int SecondHashFunc(std::string num); int HashFunc(std::string num, int iteration); From e7463232d6817e21e3c079b876dfcb5e061133cf Mon Sep 17 00:00:00 2001 From: love Date: Mon, 5 May 2025 20:59:11 +0000 Subject: [PATCH 25/34] task_04 --- task_04/src/fish_days.cpp | 35 ++++++++++++++++++++++++++++ task_04/src/fish_days.hpp | 3 +++ task_04/src/test.cpp | 48 +++++++++++++++++++++++++++++++++++++-- task_08/src/main.cpp | 11 +-------- 4 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 task_04/src/fish_days.cpp create mode 100644 task_04/src/fish_days.hpp diff --git a/task_04/src/fish_days.cpp b/task_04/src/fish_days.cpp new file mode 100644 index 0000000..c9200b7 --- /dev/null +++ b/task_04/src/fish_days.cpp @@ -0,0 +1,35 @@ +#include "fish_days.hpp" + +std::vector calculate_fish_days(int N, int K, + const std::vector& prices) { + if (prices.size() == 0) { + return {}; + } + std::vector relevant_prices(K); + std::vector purchases(N, 0); + std::vector actual_days(K); + relevant_prices[0] = prices[0]; + actual_days[0] = 0; + double min_price = relevant_prices[0]; + int min_price_day = 0; + ++purchases[min_price_day]; + for (int i{1}; i < N; ++i) { + relevant_prices[i % K] = prices[i]; + actual_days[i % K] = i; + if (prices[i] <= min_price) { + min_price = prices[i]; + min_price_day = i; + } else if (min_price_day <= i - K) { + min_price = relevant_prices[0]; + min_price_day = actual_days[0]; + for (int j{1}; j < K; ++j) { + if (relevant_prices[j] <= min_price) { + min_price = relevant_prices[j]; + min_price_day = actual_days[j]; + } + } + } + ++purchases[min_price_day]; + } + return purchases; +} diff --git a/task_04/src/fish_days.hpp b/task_04/src/fish_days.hpp new file mode 100644 index 0000000..b944cff --- /dev/null +++ b/task_04/src/fish_days.hpp @@ -0,0 +1,3 @@ +#include +std::vector calculate_fish_days(int N, int K, + const std::vector& prices); \ No newline at end of file diff --git a/task_04/src/test.cpp b/task_04/src/test.cpp index 5e11617..c70d557 100644 --- a/task_04/src/test.cpp +++ b/task_04/src/test.cpp @@ -1,6 +1,50 @@ #include -TEST(TopologySort, Simple) { - ASSERT_EQ(1, 1); // Stack [] +#include "fish_days.hpp" + +TEST(FishDays, OneDay) { + std::vector expected = {1}; + ASSERT_EQ(calculate_fish_days(1, 1, {5.0}), expected); +} + +TEST(FishDays, CheapFishWeek) { + std::vector prices = {5, 5, 1, 5, 5, 5, 5}; + std::vector expected = {1, 1, 3, 0, 0, 1, 1}; + ASSERT_EQ(calculate_fish_days(7, 3, prices), expected); +} + +TEST(FishDays, AllAtOne) { + std::vector prices = {8, 9, 10, 15, 20}; + std::vector expected = {5, 0, 0, 0, 0}; + ASSERT_EQ(calculate_fish_days(5, 5, prices), expected); +} + +TEST(FishDays, EveryDay) { + std::vector prices = {10, 8, 6, 4, 2}; + std::vector expected = {1, 1, 1, 1, 1}; + ASSERT_EQ(calculate_fish_days(5, 2, prices), expected); } + +TEST(FishDays, AnotherEveryDay) { + std::vector prices(10, 5.0); + std::vector expected(10, 1); + ASSERT_EQ(calculate_fish_days(10, 3, prices), expected); +} + +TEST(FishDays, Empty) { + std::vector expected; + ASSERT_EQ(calculate_fish_days(0, 3, {}), expected); +} + +TEST(FishDays, K_is_One) { + std::vector prices = {3, 1, 4, 1, 5}; + std::vector expected = {1, 1, 1, 1, 1}; + ASSERT_EQ(calculate_fish_days(5, 1, prices), expected); +} + +TEST(FishDays, Simple) { + std::vector prices = {7, 3, 8, 2, 5, 1, 9}; + std::vector expected = {1, 2, 0, 2, 0, 2, 0}; + ASSERT_EQ(calculate_fish_days(7, 4, prices), expected); +} \ No newline at end of file diff --git a/task_08/src/main.cpp b/task_08/src/main.cpp index 80c1646..0aadcf2 100644 --- a/task_08/src/main.cpp +++ b/task_08/src/main.cpp @@ -2,13 +2,4 @@ #include "hash_table.hpp" -int main() { - HashTable hash_table(2); - hash_table.Add("a", 4); - hash_table.Add("b", 1); - hash_table.Add("c", 6); - int val = hash_table.Get("b"); - std::cout << val << "\n"; - HashTable h(-2); - return 0; -} +int main() { return 0; } From 646fe0f7c228a2fef7e8a1a55dcb85275f47d8be Mon Sep 17 00:00:00 2001 From: love Date: Wed, 7 May 2025 22:01:40 +0000 Subject: [PATCH 26/34] task_09 --- task_09/src/task.cpp | 53 ++++++++++++++++++++++++++++++++++ task_09/src/task.hpp | 9 ++++++ task_09/src/test.cpp | 68 ++++++++++++++++++++++++++++++++------------ 3 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 task_09/src/task.cpp create mode 100644 task_09/src/task.hpp diff --git a/task_09/src/task.cpp b/task_09/src/task.cpp new file mode 100644 index 0000000..1644e7c --- /dev/null +++ b/task_09/src/task.cpp @@ -0,0 +1,53 @@ +#include "task.hpp" + +#include + +std::vector IsThereSortedColumns( + const std::vector>& matrix, + const std::vector>& l_and_r) { + std::vector> prefikses_from_bools{build_prefikses(matrix)}; + std::vector ans{}; + for (auto pair : l_and_r) { + size_t l = pair.first; + size_t r = pair.second; + if (l >= matrix.size() || r >= matrix.size() || l > r) { + throw std::runtime_error("l or r is wrong"); + } + if (l == r) { + ans.push_back(true); + continue; + } + bool is_found{false}; + for (int j{0}; j < matrix[0].size(); ++j) { + if (prefikses_from_bools[r][j] - prefikses_from_bools[l][j] == + static_cast(r - l)) { + is_found = true; + break; + } + } + ans.push_back(is_found); + } + return ans; +} + +std::vector> build_prefikses( + const std::vector>& matrix) { + if (matrix.size() == 0) { + throw std::runtime_error("empty matrix"); + } + size_t columns_num = matrix[0].size(); + for (int i{0}; i < matrix.size(); ++i) { + if (matrix[i].size() != columns_num) { + throw std::runtime_error("rows should have same size"); + } + } + std::vector> prefikses(matrix.size(), + std::vector(columns_num, 0)); + for (int i{1}; i < matrix.size(); ++i) { + for (int j{0}; j < columns_num; ++j) { + prefikses[i][j] = + prefikses[i - 1][j] + (matrix[i - 1][j] <= matrix[i][j] ? 1 : 0); + } + } + return prefikses; +} diff --git a/task_09/src/task.hpp b/task_09/src/task.hpp new file mode 100644 index 0000000..3f7750c --- /dev/null +++ b/task_09/src/task.hpp @@ -0,0 +1,9 @@ +#include +#include + +std::vector IsThereSortedColumns( + const std::vector>& matrix, + const std::vector>& l_and_r); + +std::vector> build_prefikses( + const std::vector>& matrix); \ No newline at end of file diff --git a/task_09/src/test.cpp b/task_09/src/test.cpp index a42caa4..288e6d6 100644 --- a/task_09/src/test.cpp +++ b/task_09/src/test.cpp @@ -1,23 +1,55 @@ #include -#include - -TEST(CanReachNonDecreasingSegment, 1) { - // ASSERT_EQ(SolveFunction(5, 4, 6, - // std::vector>{{1, 2, 3, 5}, - // {3, 1, 3, 2}, - // {4, 5, 2, 3}, - // {5, 5, 3, 2}, - // {4, 4, 3, 4}}, - // std::vector>{ - // {1, 1}, {2, 5}, {4, 5}, {3, 5}, {1, 3}, {1, - // 5}}), - // (std::vector{"Yes", "No", "Yes", "Yes", "Yes", - // "No"})); +#include "task.hpp" + +TEST(IsThereSortedColumns, Simple) { + std::vector> matrix{{1, 0, 3}, {2, 2, 3}, {1, 0, 2}}; + std::vector> pairs{{0, 2}, {1, 1}, {0, 1}}; + std::vector ans{false, true, true}; + ASSERT_EQ(IsThereSortedColumns(matrix, pairs), ans); +} + +TEST(IsThereSortedColumns, EmptyMatrix) { + std::vector> matrix; + std::vector> pairs{{0, 0}}; + EXPECT_THROW(IsThereSortedColumns(matrix, pairs), std::runtime_error); +} + +TEST(IsThereSortedColumns, WrongRows) { + std::vector> matrix{{1, 2, 3}, {8, 9}}; + std::vector> pairs{{0, 0}}; + EXPECT_THROW(IsThereSortedColumns(matrix, pairs), std::runtime_error); +} + +TEST(IsThereSortedColumns, SingleRow) { + std::vector> matrix{{1, 2, 3}}; + std::vector> pairs{{0, 0}}; + std::vector ans{true}; + ASSERT_EQ(IsThereSortedColumns(matrix, pairs), ans); +} + +TEST(IsThereSortedColumns, OneColumnSorted) { + std::vector> matrix{{5, 1, 3}, {6, 0, 2}, {7, 0, 4}}; + std::vector> pairs{{0, 2}}; + std::vector ans{true}; + ASSERT_EQ(IsThereSortedColumns(matrix, pairs), ans); } -TEST(CanReachNonDecreasingSegment, 2) { - // ASSERT_EQ(SolveFunction(1, 1, 1, std::vector>{{1, 1}}, - // std::vector>{{1, 1}}), - // (std::vector{"Yes"})); +TEST(IsThereSortedColumns, NoSortedColumns) { + std::vector> matrix{{3, 2, 7}, {2, 3, 5}, {1, 2, 0}}; + std::vector> pairs{{0, 2}, {2, 2}, {1, 2}}; + std::vector ans{false, true, false}; + ASSERT_EQ(IsThereSortedColumns(matrix, pairs), ans); } + +TEST(IsThereSortedColumns, InvalidRange) { + std::vector> matrix{{1, 2}, {3, 4}}; + std::vector> pairs{{1, 0}}; // l > r + EXPECT_THROW(IsThereSortedColumns(matrix, pairs), std::runtime_error); +} + +TEST(IsThereSortedColumns, InvalidRange2) { + std::vector> matrix{{1, 2}, {3, 4}}; + std::vector> pairs{{0, 2}}; // r >= matrix.size() + EXPECT_THROW(IsThereSortedColumns(matrix, pairs), std::runtime_error); +} \ No newline at end of file From 2cdb4510a87543d635892ebf02c07e589dd1e804 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 10 May 2025 08:48:37 +0000 Subject: [PATCH 27/34] Camel --- task_01/src/task.cpp | 2 +- task_01/src/task.hpp | 2 +- task_01/src/test.cpp | 16 ++++++++-------- task_09/src/task.cpp | 4 ++-- task_09/src/task.hpp | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/task_01/src/task.cpp b/task_01/src/task.cpp index c7cdbd1..9adfae7 100644 --- a/task_01/src/task.cpp +++ b/task_01/src/task.cpp @@ -2,7 +2,7 @@ #include -std::pair search_numbers(int search_num, std::vector data) { +std::pair SearchNumbers(int search_num, std::vector data) { if (data.size() <= 1) { throw std::invalid_argument("vector is too small"); } diff --git a/task_01/src/task.hpp b/task_01/src/task.hpp index 5a0c501..f83a266 100644 --- a/task_01/src/task.hpp +++ b/task_01/src/task.hpp @@ -1,4 +1,4 @@ #include #include -std::pair search_numbers(int search_num, std::vector data); \ No newline at end of file +std::pair SearchNumbers(int search_num, std::vector data); \ No newline at end of file diff --git a/task_01/src/test.cpp b/task_01/src/test.cpp index 1d3356b..173ac81 100644 --- a/task_01/src/test.cpp +++ b/task_01/src/test.cpp @@ -5,44 +5,44 @@ TEST(Task1, Simple) { std::vector data{1, 3, 4, 4, 7, 11}; std::pair ans{3, 7}; - ASSERT_EQ(search_numbers(10, data), ans); + ASSERT_EQ(SearchNumbers(10, data), ans); } TEST(Task1, FirstAndLast) { std::vector data{1, 2, 3, 4, 5, 99}; std::pair ans{1, 99}; - ASSERT_EQ(search_numbers(100, data), ans); + ASSERT_EQ(SearchNumbers(100, data), ans); } TEST(Task1, Negative) { std::vector data{-5, -3, 0, 1, 2, 8}; std::pair ans{-3, 8}; - ASSERT_EQ(search_numbers(5, data), ans); + ASSERT_EQ(SearchNumbers(5, data), ans); } TEST(Task1, Simple2) { std::vector data{10, 11, 12, 13, 14, 15}; std::pair ans{10, 15}; - ASSERT_EQ(search_numbers(25, data), ans); + ASSERT_EQ(SearchNumbers(25, data), ans); } TEST(Task1, SmallVector) { std::vector data{1, 2}; std::pair ans{1, 2}; - ASSERT_EQ(search_numbers(3, data), ans); + ASSERT_EQ(SearchNumbers(3, data), ans); } TEST(Task1, NoPair) { std::vector data{1, 2, 3, 4, 5}; - ASSERT_THROW(search_numbers(100, data), std::invalid_argument); + ASSERT_THROW(SearchNumbers(100, data), std::invalid_argument); } TEST(Task1, Empty) { std::vector data; - ASSERT_THROW(search_numbers(10, data), std::invalid_argument); + ASSERT_THROW(SearchNumbers(10, data), std::invalid_argument); } TEST(Task1, SingleElementVector) { std::vector data{5}; - ASSERT_THROW(search_numbers(5, data), std::invalid_argument); + ASSERT_THROW(SearchNumbers(5, data), std::invalid_argument); } diff --git a/task_09/src/task.cpp b/task_09/src/task.cpp index 1644e7c..0d66b13 100644 --- a/task_09/src/task.cpp +++ b/task_09/src/task.cpp @@ -5,7 +5,7 @@ std::vector IsThereSortedColumns( const std::vector>& matrix, const std::vector>& l_and_r) { - std::vector> prefikses_from_bools{build_prefikses(matrix)}; + std::vector> prefikses_from_bools{BuildPrefikses(matrix)}; std::vector ans{}; for (auto pair : l_and_r) { size_t l = pair.first; @@ -30,7 +30,7 @@ std::vector IsThereSortedColumns( return ans; } -std::vector> build_prefikses( +std::vector> BuildPrefikses( const std::vector>& matrix) { if (matrix.size() == 0) { throw std::runtime_error("empty matrix"); diff --git a/task_09/src/task.hpp b/task_09/src/task.hpp index 3f7750c..5889a59 100644 --- a/task_09/src/task.hpp +++ b/task_09/src/task.hpp @@ -5,5 +5,5 @@ std::vector IsThereSortedColumns( const std::vector>& matrix, const std::vector>& l_and_r); -std::vector> build_prefikses( +std::vector> BuildPrefikses( const std::vector>& matrix); \ No newline at end of file From ed441a479657bec3d7153da755746c144591a973 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 10 May 2025 09:48:00 +0000 Subject: [PATCH 28/34] destructor stack --- task_01/src/task.cpp | 3 ++- task_01/src/task.hpp | 2 +- task_02/src/stack.hpp | 23 +++++++++++++++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/task_01/src/task.cpp b/task_01/src/task.cpp index 9adfae7..c688469 100644 --- a/task_01/src/task.cpp +++ b/task_01/src/task.cpp @@ -2,7 +2,8 @@ #include -std::pair SearchNumbers(int search_num, std::vector data) { +std::pair SearchNumbers(int search_num, + const std::vector& data) { if (data.size() <= 1) { throw std::invalid_argument("vector is too small"); } diff --git a/task_01/src/task.hpp b/task_01/src/task.hpp index f83a266..ca04052 100644 --- a/task_01/src/task.hpp +++ b/task_01/src/task.hpp @@ -1,4 +1,4 @@ #include #include -std::pair SearchNumbers(int search_num, std::vector data); \ No newline at end of file +std::pair SearchNumbers(int search_num, const std::vector& data); \ No newline at end of file diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp index f628f50..045104b 100644 --- a/task_02/src/stack.hpp +++ b/task_02/src/stack.hpp @@ -17,6 +17,13 @@ template class Stack { public: Stack(){}; + ~Stack() { + while (head != nullptr) { + Node* old_head = head; + head = head->prev; + delete old_head; + } + } void Push(T value); T Pop(); @@ -29,6 +36,18 @@ template class MinStack { public: MinStack(){}; + ~MinStack() { + while (head != nullptr) { + Node* old_head = head; + Node* old_head_min = head_min; + + head = head->prev; + head_min = head_min->prev; + + delete old_head; + delete old_head_min; + } + } void Push(T value); T Pop(); T GetMin(); @@ -86,7 +105,7 @@ void MinStack::Push(T value) { template requires(std::totally_ordered) T MinStack::Pop() { - if (head == nullptr) { + if (!head || !head_min) { throw EmptyStackError(); } Node* del_node = head; @@ -102,7 +121,7 @@ T MinStack::Pop() { template requires(std::totally_ordered) T MinStack::GetMin() { - if (head_min == nullptr) { + if (!head_min) { throw EmptyStackError(); } return head_min->value; From 234d344bd8a7a647c96432c077a142cfe880333e Mon Sep 17 00:00:00 2001 From: love Date: Sat, 10 May 2025 10:02:18 +0000 Subject: [PATCH 29/34] small changes --- task_08/src/hash_table.cpp | 8 +++++--- task_08/src/hash_table.hpp | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/task_08/src/hash_table.cpp b/task_08/src/hash_table.cpp index 7a3f34d..86bc529 100644 --- a/task_08/src/hash_table.cpp +++ b/task_08/src/hash_table.cpp @@ -1,10 +1,12 @@ #include "hash_table.hpp" -int HashTable::SecondHashFunc(std::string key) { return 1; } +int HashTable::SecondHashFunc(const std::string& key) { return 1; } -int HashTable::FirstHashFunc(std::string key) { return base_hasher(key); } +int HashTable::FirstHashFunc(const std::string& key) { + return base_hasher(key); +} -int HashTable::HashFunc(std::string key, int iteration) { +int HashTable::HashFunc(const std::string& key, int iteration) { return (FirstHashFunc(key) + iteration * SecondHashFunc(key)) % array.size(); } diff --git a/task_08/src/hash_table.hpp b/task_08/src/hash_table.hpp index 7d7808c..fe193db 100644 --- a/task_08/src/hash_table.hpp +++ b/task_08/src/hash_table.hpp @@ -30,7 +30,7 @@ struct HashTable { void UpdateArray(); int FindIndex(const std::string& key); // находит, если существует // если нет такого, возвращает -1 - int FirstHashFunc(std::string num); - int SecondHashFunc(std::string num); - int HashFunc(std::string num, int iteration); + int FirstHashFunc(const std::string& num); + int SecondHashFunc(const std::string& num); + int HashFunc(const std::string& num, int iteration); }; \ No newline at end of file From a1d8b0ede0f70ca2d2e0fd82adf555c8cc48f9f2 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 10 May 2025 10:04:28 +0000 Subject: [PATCH 30/34] small changes --- task_08/src/hash_table.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/task_08/src/hash_table.cpp b/task_08/src/hash_table.cpp index 86bc529..8e3a2f3 100644 --- a/task_08/src/hash_table.cpp +++ b/task_08/src/hash_table.cpp @@ -65,6 +65,9 @@ void HashTable::Add(const std::string& new_key, int new_value) { array[index].value = new_value; return; } + if (full_elements > array.size() / 2) { + UpdateArray(); + } for (int i{0}; i < array.size(); ++i) { index = HashFunc(new_key, i); if (array[index].condition == Condition::Empty || @@ -73,9 +76,6 @@ void HashTable::Add(const std::string& new_key, int new_value) { array[index].value = new_value; array[index].condition = Condition::Full; full_elements += 1; - if (full_elements > array.size() / 2) { - UpdateArray(); - } return; } } From dd61ceaeab3ea7b68d6da3f8c298f487a3d9a315 Mon Sep 17 00:00:00 2001 From: love Date: Tue, 27 May 2025 20:59:21 +0000 Subject: [PATCH 31/34] tests for iterator and other changes --- task_02/src/stack.hpp | 4 +-- task_03/src/days_before_hot.cpp | 5 +++ task_03/src/days_before_hot.hpp | 4 --- task_07/src/avl_tree.hpp | 20 +++++++++++ task_07/src/test.cpp | 64 +++++++++++++++++++++++++++++++++ task_08/src/hash_table.cpp | 4 +-- task_08/src/hash_table.hpp | 2 +- task_09/src/task.cpp | 15 ++++---- task_09/src/task.hpp | 2 +- 9 files changed, 102 insertions(+), 18 deletions(-) diff --git a/task_02/src/stack.hpp b/task_02/src/stack.hpp index 045104b..b47652b 100644 --- a/task_02/src/stack.hpp +++ b/task_02/src/stack.hpp @@ -50,7 +50,7 @@ class MinStack { } void Push(T value); T Pop(); - T GetMin(); + T const GetMin(); private: Node* head = nullptr; @@ -120,7 +120,7 @@ T MinStack::Pop() { template requires(std::totally_ordered) -T MinStack::GetMin() { +T const MinStack::GetMin() { if (!head_min) { throw EmptyStackError(); } diff --git a/task_03/src/days_before_hot.cpp b/task_03/src/days_before_hot.cpp index a75f943..7e5093c 100644 --- a/task_03/src/days_before_hot.cpp +++ b/task_03/src/days_before_hot.cpp @@ -1,5 +1,10 @@ #include "days_before_hot.hpp" +struct TemperatureWithDayIndex { + double temperature; + int day_index; +}; + std::vector DaysBeforeHot(std::vector temperatures) { std::vector days_before_hot(temperatures.size()); std::stack hotter_temperatures{}; diff --git a/task_03/src/days_before_hot.hpp b/task_03/src/days_before_hot.hpp index 287bd37..ba5196f 100644 --- a/task_03/src/days_before_hot.hpp +++ b/task_03/src/days_before_hot.hpp @@ -1,8 +1,4 @@ #include #include -struct TemperatureWithDayIndex { - double temperature; - int day_index; -}; std::vector DaysBeforeHot(std::vector temperatures); \ No newline at end of file diff --git a/task_07/src/avl_tree.hpp b/task_07/src/avl_tree.hpp index ae19f69..2eaf47a 100644 --- a/task_07/src/avl_tree.hpp +++ b/task_07/src/avl_tree.hpp @@ -14,6 +14,26 @@ class AvlTree { } } + bool operator==(const AvlTree& other) const { + if (this == &other) { + return true; + } + if (head == nullptr && other.head == nullptr) { + return true; + } + if (head == nullptr || other.head == nullptr) { + return false; + } + for (auto it = begin(), it_other = other.begin(); + it != end() && it_other != other.end(); ++it, ++it_other) { + if (*it != *it_other) { + return false; + } + } + return true; + } + bool operator!=(const AvlTree& other) const { return !(*this == other); } + void Del(int del_key); void Add(int new_key, int data); diff --git a/task_07/src/test.cpp b/task_07/src/test.cpp index 2129e63..0ffce4c 100644 --- a/task_07/src/test.cpp +++ b/task_07/src/test.cpp @@ -67,4 +67,68 @@ TEST(AvlCoutTest, SingleElement) { std::ostringstream oss; oss << tree; EXPECT_EQ(oss.str(), "{(5, 6)}"); +} + +TEST(AvlIteratorTest, IterationOrder) { + std::vector> pairs{{5, 5}, {3, 3}, {7, 7}, {2, 2}, + {4, 4}, {6, 6}, {8, 8}}; + AvlTree tree(pairs); + + std::vector> result; + for (const auto& kv : tree) { + result.push_back(kv); + } + + std::vector> expected{{2, 2}, {3, 3}, {4, 4}, {5, 5}, + {6, 6}, {7, 7}, {8, 8}}; + + EXPECT_EQ(result, expected); +} + +TEST(AvlIteratorTest, EmptyTree) { + AvlTree empty_tree; + std::vector> result; + for (const auto& kv : empty_tree) { + result.push_back(kv); + } + EXPECT_TRUE(result.empty()); +} + +TEST(AvlIteratorTest, SingleElement) { + AvlTree tree; + tree.Add(5, 6); + std::vector> result; + for (const auto& kv : tree) { + result.push_back(kv); + } + EXPECT_EQ(result.size(), 1); + EXPECT_EQ(result[0].first, 5); + EXPECT_EQ(result[0].second, 6); +} + +TEST(AvlIteratorTest, MixedOperations) { + AvlTree tree; + tree.Add(5, 5); + tree.Add(3, 3); + tree.Add(7, 7); + + std::vector> result; + for (const auto& kv : tree) { + result.push_back(kv); + } + + std::vector> expected{{3, 3}, {5, 5}, {7, 7}}; + + EXPECT_EQ(result, expected); + + tree.Del(3); + + result.clear(); + for (const auto& kv : tree) { + result.push_back(kv); + } + + expected = {{5, 5}, {7, 7}}; + + EXPECT_EQ(result, expected); } \ No newline at end of file diff --git a/task_08/src/hash_table.cpp b/task_08/src/hash_table.cpp index 8e3a2f3..899bbee 100644 --- a/task_08/src/hash_table.cpp +++ b/task_08/src/hash_table.cpp @@ -20,10 +20,10 @@ HashTable::HashTable() { array = vec; } -HashTable::HashTable(std::vector> input) { +HashTable::HashTable(const std::vector> input) { std::vector vec(input.size() * 3); array = vec; - for (auto elem : input) { + for (const auto elem : input) { Add(elem.first, elem.second); } } diff --git a/task_08/src/hash_table.hpp b/task_08/src/hash_table.hpp index fe193db..1d90684 100644 --- a/task_08/src/hash_table.hpp +++ b/task_08/src/hash_table.hpp @@ -12,7 +12,7 @@ struct HashTable { public: HashTable(); HashTable(size_t size); - HashTable(std::vector> input); + HashTable(const std::vector> input); void Add(const std::string& new_key, int new_value); void Del(const std::string& del_key); int Get(const std::string& key); diff --git a/task_09/src/task.cpp b/task_09/src/task.cpp index 0d66b13..d3fd1b3 100644 --- a/task_09/src/task.cpp +++ b/task_09/src/task.cpp @@ -5,7 +5,7 @@ std::vector IsThereSortedColumns( const std::vector>& matrix, const std::vector>& l_and_r) { - std::vector> prefikses_from_bools{BuildPrefikses(matrix)}; + std::vector> prefixes_from_bools{BuildPrefixes(matrix)}; std::vector ans{}; for (auto pair : l_and_r) { size_t l = pair.first; @@ -19,7 +19,7 @@ std::vector IsThereSortedColumns( } bool is_found{false}; for (int j{0}; j < matrix[0].size(); ++j) { - if (prefikses_from_bools[r][j] - prefikses_from_bools[l][j] == + if (prefixes_from_bools[r][j] - prefixes_from_bools[l][j] == static_cast(r - l)) { is_found = true; break; @@ -30,7 +30,7 @@ std::vector IsThereSortedColumns( return ans; } -std::vector> BuildPrefikses( +std::vector> BuildPrefixes( const std::vector>& matrix) { if (matrix.size() == 0) { throw std::runtime_error("empty matrix"); @@ -41,13 +41,12 @@ std::vector> BuildPrefikses( throw std::runtime_error("rows should have same size"); } } - std::vector> prefikses(matrix.size(), - std::vector(columns_num, 0)); + std::vector> p(matrix.size(), + std::vector(columns_num, 0)); for (int i{1}; i < matrix.size(); ++i) { for (int j{0}; j < columns_num; ++j) { - prefikses[i][j] = - prefikses[i - 1][j] + (matrix[i - 1][j] <= matrix[i][j] ? 1 : 0); + p[i][j] = p[i - 1][j] + (matrix[i - 1][j] <= matrix[i][j] ? 1 : 0); } } - return prefikses; + return p; } diff --git a/task_09/src/task.hpp b/task_09/src/task.hpp index 5889a59..f8582f0 100644 --- a/task_09/src/task.hpp +++ b/task_09/src/task.hpp @@ -5,5 +5,5 @@ std::vector IsThereSortedColumns( const std::vector>& matrix, const std::vector>& l_and_r); -std::vector> BuildPrefikses( +std::vector> BuildPrefixes( const std::vector>& matrix); \ No newline at end of file From 37ea51cb897c00e145c7b1d4fcdfd056c5ef030a Mon Sep 17 00:00:00 2001 From: love Date: Tue, 27 May 2025 21:18:50 +0000 Subject: [PATCH 32/34] better fish --- task_04/src/fish_days.cpp | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/task_04/src/fish_days.cpp b/task_04/src/fish_days.cpp index c9200b7..09cd3f2 100644 --- a/task_04/src/fish_days.cpp +++ b/task_04/src/fish_days.cpp @@ -2,34 +2,29 @@ std::vector calculate_fish_days(int N, int K, const std::vector& prices) { - if (prices.size() == 0) { - return {}; - } - std::vector relevant_prices(K); + if (prices.empty()) return {}; + std::vector purchases(N, 0); - std::vector actual_days(K); - relevant_prices[0] = prices[0]; - actual_days[0] = 0; - double min_price = relevant_prices[0]; int min_price_day = 0; - ++purchases[min_price_day]; - for (int i{1}; i < N; ++i) { - relevant_prices[i % K] = prices[i]; - actual_days[i % K] = i; - if (prices[i] <= min_price) { + double min_price = prices[0]; + ++purchases[0]; + + for (int i = 1; i < N; ++i) { + if (prices[i] <= min_price) { // если новый минимум min_price = prices[i]; min_price_day = i; - } else if (min_price_day <= i - K) { - min_price = relevant_prices[0]; - min_price_day = actual_days[0]; - for (int j{1}; j < K; ++j) { - if (relevant_prices[j] <= min_price) { - min_price = relevant_prices[j]; - min_price_day = actual_days[j]; + } else if (min_price_day <= i - K) { // если минимум устарел + min_price = prices[i - K + 1]; + min_price_day = i - K + 1; + for (int j = i - K + 2; j <= i; + ++j) { // пересчёт минимума в окне [i-K+1, i] + if (prices[j] <= min_price) { + min_price = prices[j]; + min_price_day = j; } } } ++purchases[min_price_day]; } return purchases; -} +} \ No newline at end of file From 73ef56d4f1734e3e7d14e824e6c53042044360b8 Mon Sep 17 00:00:00 2001 From: love Date: Sat, 31 May 2025 09:28:04 +0000 Subject: [PATCH 33/34] inplace Quicksort --- task_05/src/quick_sort.cpp | 32 ++++++++++++++++++++++---------- task_05/src/quick_sort.hpp | 4 +--- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/task_05/src/quick_sort.cpp b/task_05/src/quick_sort.cpp index 7d1e139..f8b8360 100644 --- a/task_05/src/quick_sort.cpp +++ b/task_05/src/quick_sort.cpp @@ -1,14 +1,26 @@ #include "quick_sort.hpp" -std::vector QuickSort(std::vector input) { - if (input.size() <= 1) { - return input; +#include +#include + +void QuickSortInplace(std::vector& arr, int left, int right) { + if (left >= right) return; + double pivot = arr[right]; + int i = left; + for (int j = left; j < right; ++j) { + if (arr[j] < pivot) { + std::swap(arr[i], arr[j]); + ++i; + } } - double elem = input[0]; - std::vector eq{Eq(elem, input)}; - std::vector bigger{QuickSort(Bigger(elem, input))}; - std::vector ans{QuickSort(Smaller(elem, input))}; - ans.insert(ans.end(), eq.begin(), eq.end()); - ans.insert(ans.end(), bigger.begin(), bigger.end()); - return ans; + std::swap(arr[i], arr[right]); + QuickSortInplace(arr, left, i - 1); + QuickSortInplace(arr, i + 1, right); +} + +// обертка +std::vector QuickSort(const std::vector& input) { + std::vector arr = input; + if (!arr.empty()) QuickSortInplace(arr, 0, arr.size() - 1); + return arr; } \ No newline at end of file diff --git a/task_05/src/quick_sort.hpp b/task_05/src/quick_sort.hpp index 8620c0f..1080cb2 100644 --- a/task_05/src/quick_sort.hpp +++ b/task_05/src/quick_sort.hpp @@ -1,5 +1,3 @@ #include -#include "../../lib/src/util.hpp" - -std::vector QuickSort(std::vector input); \ No newline at end of file +std::vector QuickSort(const std::vector& input); \ No newline at end of file From 796b51c4bd440e69761d46e34e56431e60424588 Mon Sep 17 00:00:00 2001 From: love Date: Thu, 19 Jun 2025 20:15:28 +0000 Subject: [PATCH 34/34] clang_tidy --- task_05/src/quick_sort.cpp | 2 +- task_08/src/hash_table.cpp | 4 ++-- task_08/src/hash_table.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/task_05/src/quick_sort.cpp b/task_05/src/quick_sort.cpp index f8b8360..3c039ae 100644 --- a/task_05/src/quick_sort.cpp +++ b/task_05/src/quick_sort.cpp @@ -3,7 +3,7 @@ #include #include -void QuickSortInplace(std::vector& arr, int left, int right) { +static void QuickSortInplace(std::vector& arr, int left, int right) { if (left >= right) return; double pivot = arr[right]; int i = left; diff --git a/task_08/src/hash_table.cpp b/task_08/src/hash_table.cpp index 899bbee..dad2087 100644 --- a/task_08/src/hash_table.cpp +++ b/task_08/src/hash_table.cpp @@ -20,10 +20,10 @@ HashTable::HashTable() { array = vec; } -HashTable::HashTable(const std::vector> input) { +HashTable::HashTable(const std::vector>& input) { std::vector vec(input.size() * 3); array = vec; - for (const auto elem : input) { + for (const auto& elem : input) { Add(elem.first, elem.second); } } diff --git a/task_08/src/hash_table.hpp b/task_08/src/hash_table.hpp index 1d90684..27d8505 100644 --- a/task_08/src/hash_table.hpp +++ b/task_08/src/hash_table.hpp @@ -12,7 +12,7 @@ struct HashTable { public: HashTable(); HashTable(size_t size); - HashTable(const std::vector> input); + HashTable(const std::vector>& input); void Add(const std::string& new_key, int new_value); void Del(const std::string& del_key); int Get(const std::string& key);