Skip to content

Homework 2 #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/additional_tasks)

file(GLOB_RECURSE tasks_dirs LIST_DIRECTORIES true ".")


foreach(dir ${tasks_dirs})
IF(IS_DIRECTORY ${dir})
IF(${dir} MATCHES "task_0[0-9]$" AND NOT ${dir} MATCHES "build")
97 changes: 97 additions & 0 deletions THEORY/theory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Стеки, Очереди, Деки (C++)

## Стек

### Определение

Стеком (англ. stack) называется хранилище данных, в котором можно работать только с одним элементом: тем, который был добавлен в стек последним. Стек должен поддерживать следующие операции:

- `push`: Добавить (положить) в конец стека новый элемент.
- `pop`: Извлечь из стека последний элемент.
- `back`: Узнать значение последнего элемента (не удаляя его).
- `size`: Узнать количество элементов в стеке.
- `clear`: Очистить стек (удалить из него все элементы).

### Структура данных Stack

- stack(); // Конструктор
- ~stack(); // Деструктор
- void push(int d); // Добавить в стек новый элемент
- int pop(); // Удалить из стека последний элемент и вернуть его значение
- int back(); // Вернуть значение последнего элемента
- int size(); // Вернуть количество элементов в стеке
- void clear(); // Очистить стек


## Очередь

### Определение

Очередью (англ. queue) называется структура данных, в которой элементы кладутся в конец, а извлекаются из начала. Первым из очереди будет извлечен тот элемент, который будет добавлен раньше других.

### Структура данных Queue

- queue(); // Конструктор
- ~queue(); // Деструктор
- void push(int d); // Добавить в очередь новый элемент
- int pop(); // Удалить из очереди первый элемент и вернуть его значение
- int front(); // Вернуть значение первого элемента
- int size(); // Вернуть количество элементов в очереди
- void clear(); // Очистить очередь

## Дек

### Определение

Деком (англ. deque – аббревиатура от double-ended queue, двухсторонняя очередь) называется структура данных, в которую можно удалять и добавлять элементы как в начало, так и в конец.

### Структура данных Deque

- push_front Добавить (положить) в начало дека новый элемент
- push_back Добавить (положить) в конец дека новый элемент
- pop_front Извлечь из дека первый элемент
- pop_back Извлечь из дека последний элемент
- front Узнать значение первого элемента (не удаляя его)
- back Узнать значение последнего элемента (не удаляя его)
- size Узнать количество элементов в деке
- clear Очистить дек (удалить из него все элементы)


## Упражнения

### Упражнение A - Простой стек

- Реализуйте структуру данных "стек", реализовав все указанные методы.
- Напишите программу (функцию main), содержащую описание стека и моделирующую работу стека.

### Упражнение B - Стек с обработкой ошибок

- Аналогично предыдущему заданию, только снимается ограничение на корректность вызовов методов back и pop.

### Упражнение C - Стек без ограничения на размер

- Реализуйте стек динамического размера, то есть ограниченный только объемом свободной оперативной памяти.

### Упражнение D - Простая очередь

- Реализуйте простейшую очередь, размер которой не превосходит 100 элементов.

### Упражнение E - Очередь с обработкой ошибок

- Аналогично заданию B, но для очереди.

### Упражнение F - Очередь без ограничений на размер

- Аналогично заданию C, но для очереди.

### Упражнение G - Простой дек

- Аналогично заданиям A и D, но для дека.

### Упражнение H - Дек с обработкой ошибок

- Аналогично заданиям B и E, но для дека.

### Упражнение I - Дек неограниченного размера

- Аналогично заданию C и F, но для дека.
22 changes: 20 additions & 2 deletions task_03/src/test.cpp
Original file line number Diff line number Diff line change
@@ -3,6 +3,24 @@

#include "topology_sort.hpp"

TEST(TopologySort, Simple) {
ASSERT_EQ(1, 1); // Stack []
TEST(DaysBeforeWarming, Simple) {
std::vector<int> temperatures = {1, 2, 3, 4, 5};
std::vector<int> correct_answer = {1, 1, 1, 1, 0};
ASSERT_EQ(DaysBeforeWarming(temperatures), correct_answer);

temperatures = {1};
correct_answer = {0};
ASSERT_EQ(DaysBeforeWarming(temperatures), correct_answer);

temperatures = {0, 0, 0, 0, 0, 5};
correct_answer = {5, 4, 3, 2, 1, 0};
ASSERT_EQ(DaysBeforeWarming(temperatures), correct_answer);

temperatures = {0, 0, 0, 0, 0, 0};
correct_answer = {0, 0, 0, 0, 0, 0};
ASSERT_EQ(DaysBeforeWarming(temperatures), correct_answer);

temperatures = {3, 12, 4, 4, 6, 2, 1, 9, 2};
correct_answer = {1, 0, 2, 1, 3, 2, 1, 0, 0};
ASSERT_EQ(DaysBeforeWarming(temperatures), correct_answer);
}
26 changes: 26 additions & 0 deletions task_03/src/topology_sort.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,27 @@
#include "topology_sort.hpp"

std::vector<int> DaysBeforeWarming(std::vector<int> temperatures) {
std::vector<int> answer(temperatures.size());
for (int i = 0; i < temperatures.size(); i++) {
answer[i] = 1;
bool was_warmer_found = false;
for (int j = i + 1; j < temperatures.size() and not was_warmer_found; j++) {
if (temperatures[i] >=
temperatures[j]) { // skip days, when tempreture is lower
answer[i] += 1;
} else if ((temperatures[i] < temperatures[j]) &
(j == i + 1)) { // case, when warmer day is rigth next
answer[i] = 1;
was_warmer_found = true;
} else if ((temperatures[i] < temperatures[j]) &
(j != i + 1)) { // case, when warmer day is rigth next
was_warmer_found = true;
}
}

if (not was_warmer_found) {
answer[i] = 0;
}
}
return answer;
}
3 changes: 3 additions & 0 deletions task_03/src/topology_sort.hpp
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
#pragma once
#include <vector>

std::vector<int> DaysBeforeWarming(std::vector<int> temperatures);
51 changes: 51 additions & 0 deletions task_04/src/heap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "heap.hpp"

int Heap::PopMin() {
if (data_.size() != 0) {
int minimum = data_[0];
std::swap(data_[0], data_[data_.size() - 1]);
data_.pop_back(); // min is already at last position

// Sift Down (O(logn))
int current_index = 0;
int left_child_index = 1;
int right_child_index = 2;

while ((left_child_index<data_.size() & data_[current_index]>
data_[left_child_index]) ||
(right_child_index<data_.size() & data_[current_index]>
data_[right_child_index])) {
if (right_child_index < data_.size() &
data_[right_child_index] < data_[left_child_index]) {
std::swap(data_[right_child_index], data_[current_index]);
current_index = right_child_index;
left_child_index = 2 * current_index + 1;
right_child_index = 2 * current_index + 2;
} else {
std::swap(data_[left_child_index], data_[current_index]);
current_index = left_child_index;
left_child_index = 2 * current_index + 1;
right_child_index = 2 * current_index + 2;
}
}

return minimum;
} else {
std::cout << "empty heap";
return {};
}
}

void Heap::Insert(int x) {
data_.push_back(x);

// Sift Up (O(logn))
int current_index = data_.size() - 1;
int parent_index = (current_index - 1) / 2;

while (data_[current_index]<data_[parent_index] & current_index> 0) {
std::swap(data_[current_index], data_[parent_index]);
current_index = (current_index - 1) / 2;
parent_index = (current_index - 1) / 2;
}
}
15 changes: 15 additions & 0 deletions task_04/src/heap.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once
#include <iostream>
#include <vector>

class Heap {
public:
Heap() { data_ = {}; }
int PopMin();
void Insert(int x);
std::vector<int> GetData() { return data_; }
void CleanHeap() { data_ = {}; }

private:
std::vector<int> data_;
};
30 changes: 28 additions & 2 deletions task_04/src/test.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@

#include <gtest/gtest.h>

TEST(TopologySort, Simple) {
ASSERT_EQ(1, 1); // Stack []
#include <vector>

#include "heap.hpp"

TEST(HeapTest, Simple) {
Heap heap;
std::vector<int> answer = {};
heap.PopMin();
ASSERT_EQ(heap.GetData(), answer); // pop from empty heap

heap.Insert(1);
heap.Insert(2);
heap.Insert(3);
heap.Insert(4);
heap.Insert(5);
heap.Insert(6);

heap.Insert(0);
answer = {0, 2, 1, 4, 5, 6, 3};
ASSERT_EQ(heap.GetData(), answer); // insert key, smaller than its parent

heap.PopMin();
answer = {1, 2, 3, 4, 5, 6};
ASSERT_EQ(heap.GetData(), answer); // pop from full heap

heap.Insert(100);
answer = {1, 2, 3, 4, 5, 6, 100};
ASSERT_EQ(heap.GetData(), answer); // insert key, smaller than its parent
}
61 changes: 61 additions & 0 deletions task_05/src/bogo_sort.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "bogo_sort.hpp"

int Search(std::vector<int> massive, int num) {
for (int i = 0; i < massive.size(); i++) {
if (massive[i] == num) {
return i;
}
}
return -1;
}

std::vector<int> ShuffleIndexes(int n) {
std::vector<int> random_nums(n);
for (int i = 0; i < n; i) {
int rand_num = std::experimental::randint(1, n);
if (Search(random_nums, rand_num) == -1) {
random_nums[i] = rand_num;
i++;
}
}
for (int i = 0; i < n; i++) {
random_nums[i]--;
}

return random_nums;
}

std::vector<int> ShuffleMassive(std::vector<int> massive) {
std::vector<int> random_indexes = ShuffleIndexes(massive.size());
std::vector<int> new_massive(massive.size());

for (int i = 0; i < massive.size(); i++) {
new_massive[i] = massive[random_indexes[i]];
}
return new_massive;
}

bool IsSorted(std::vector<int> massive) {
for (int i = 0; i < massive.size() - 1; i++) {
if (massive[i] > massive[i + 1]) {
return false;
}
}
return true;
}

// O(n!)
std::vector<int> BogoSort(std::vector<int> massive) {
if (massive.size() == 0) {
return massive;
}
if (IsSorted(massive)) {
return massive;
} else {
std::vector<int> new_massive = ShuffleMassive(massive);
while (not IsSorted(new_massive)) {
new_massive = ShuffleMassive(massive);
}
return new_massive;
}
}
18 changes: 18 additions & 0 deletions task_05/src/bogo_sort.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include <algorithm>
#include <cstddef>
#include <experimental/random>
#include <iostream>
#include <optional>
#include <valarray>
#include <vector>

int Search(std::vector<int> massive, int num);
bool IsSorted(std::vector<int> massive);

std::vector<int> ShuffleIndexes(int n);
std::vector<int> ShuffleMassive(std::vector<int> massive);

// O(n!)
std::vector<int> BogoSort(std::vector<int> massive);
15 changes: 15 additions & 0 deletions task_05/src/bubble_sort.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "bubble_sort.hpp"

// O(n^2)
std::vector<int> BubbleSort(std::vector<int> massive) {
for (int i = 0; i < massive.size(); i++) {
for (int j = 0; j < massive.size() - i - 1; j++) {
if (massive[j] > massive[j + 1]) {
int temporary = massive[j];
massive[j] = massive[j + 1];
massive[j + 1] = temporary;
}
}
}
return massive;
}
11 changes: 11 additions & 0 deletions task_05/src/bubble_sort.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include <algorithm>
#include <cstddef>
#include <experimental/random>
#include <iostream>
#include <optional>
#include <valarray>
#include <vector>

std::vector<int> BubbleSort(std::vector<int> massive);
Loading