├── Seminar1 ├── .gitignore ├── CMakeLists.txt └── main.cpp ├── Seminar2 ├── .gitignore ├── CMakeLists.txt └── main.cpp ├── Seminar3 ├── .gitignore ├── CMakeLists.txt └── main.cpp ├── Seminar4 ├── .gitignore ├── CMakeLists.txt └── main.cpp ├── Seminar5 ├── .gitignore ├── CMakeLists.txt └── main.cpp ├── Seminar6 ├── .gitignore ├── CMakeLists.txt ├── puzzle8.hpp ├── main.cpp ├── position.hpp ├── puzzle8.cpp └── position.cpp ├── Seminar7 ├── .gitignore ├── CMakeLists.txt └── main.cpp ├── Seminar8 ├── .gitignore ├── CMakeLists.txt └── main.cpp ├── Seminar9 ├── .gitignore ├── CMakeLists.txt └── main.cpp └── README.md /Seminar1/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | cmake-build-debug 3 | -------------------------------------------------------------------------------- /Seminar2/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | cmake-build-debug 3 | -------------------------------------------------------------------------------- /Seminar3/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | cmake-build-debug 3 | -------------------------------------------------------------------------------- /Seminar4/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | cmake-build-debug 3 | -------------------------------------------------------------------------------- /Seminar5/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | cmake-build-debug 3 | -------------------------------------------------------------------------------- /Seminar6/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | cmake-build-debug 3 | -------------------------------------------------------------------------------- /Seminar7/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | cmake-build-debug 3 | -------------------------------------------------------------------------------- /Seminar8/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | cmake-build-debug 3 | -------------------------------------------------------------------------------- /Seminar9/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | cmake-build-debug 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Made2019Autumn 2 | Примеры кода на семинарах по Алгоритмам и структурам данных в Академии Больших Данных Mail.ru. 3 | 4 | Осень 2019. 5 | -------------------------------------------------------------------------------- /Seminar5/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(Sem5) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | add_executable(Sem5 main.cpp) -------------------------------------------------------------------------------- /Seminar1/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(Seminar1) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | add_executable(Seminar1 main.cpp) -------------------------------------------------------------------------------- /Seminar2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(Seminar2) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | add_executable(Seminar2 main.cpp) -------------------------------------------------------------------------------- /Seminar3/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(Seminar3) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | add_executable(Seminar3 main.cpp) -------------------------------------------------------------------------------- /Seminar4/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(Seminar4) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | add_executable(Seminar4 main.cpp) -------------------------------------------------------------------------------- /Seminar7/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(Seminar7) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | add_executable(Seminar7 main.cpp) -------------------------------------------------------------------------------- /Seminar8/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(Seminar8) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | add_executable(Seminar8 main.cpp) -------------------------------------------------------------------------------- /Seminar9/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(Seminar9) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | add_executable(Seminar9 main.cpp) -------------------------------------------------------------------------------- /Seminar6/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(Sem6) 3 | 4 | set(CMAKE_CXX_STANDARD 14) 5 | 6 | add_executable(Sem6 main.cpp puzzle8.cpp position.cpp) -------------------------------------------------------------------------------- /Seminar6/puzzle8.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Stepan Matskevich on 2019-11-23. 3 | // 4 | #include "position.hpp" 5 | 6 | std::pair> SolvePuzzle8(const position& start); 7 | -------------------------------------------------------------------------------- /Seminar6/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "puzzle8.hpp" 4 | 5 | int main() { 6 | //position start{{1, 2, 3, 4, 0, 6, 7, 5, 8}, 4}; 7 | position start{{2, 4, 3, 1, 0, 6, 7, 5, 8}, 4}; 8 | const auto result = SolvePuzzle8(start); 9 | 10 | if (result.first) { 11 | for (const auto move : result.second) { 12 | std::cout << move; 13 | } 14 | } else { 15 | std::cout << "NO SOLUTION"; 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /Seminar6/position.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Stepan Matskevich on 2019-11-23. 3 | // 4 | #pragma once 5 | 6 | #include 7 | 8 | const size_t HashParameter = 37; 9 | 10 | struct position { 11 | std::vector chips; 12 | char zero_place; 13 | 14 | bool IsFinish() const; 15 | std::vector Siblings() const; 16 | 17 | bool operator==(const position& other) const; 18 | bool operator!=(const position& other) const { return !operator==(other); } 19 | }; 20 | 21 | namespace std { 22 | template <> 23 | struct hash { 24 | size_t operator()(const position& key) const { 25 | size_t value = 0; 26 | for (auto chip : key.chips) { 27 | value = HashParameter * value + static_cast(chip); 28 | } 29 | return value; 30 | } 31 | }; 32 | } 33 | 34 | const position FinishPosition{{1, 2, 3, 4, 5, 6, 7, 8, 0}, 8}; 35 | 36 | char GetMoveSymbol(const position& from, const position& to); 37 | -------------------------------------------------------------------------------- /Seminar6/puzzle8.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Stepan Matskevich on 2019-11-23. 3 | // 4 | 5 | #include "puzzle8.hpp" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | bool BFS(const position& start, std::unordered_map& parents) { 12 | std::queue positions_queue; 13 | positions_queue.push(start); 14 | while (!positions_queue.empty()) { 15 | position current = positions_queue.front(); 16 | positions_queue.pop(); 17 | for (auto sibling : current.Siblings()) { 18 | if (parents.count(sibling)) { 19 | continue; 20 | } 21 | parents[sibling] = current; 22 | if (sibling.IsFinish()) { 23 | return true; 24 | } 25 | positions_queue.push(sibling); 26 | } 27 | } 28 | return false; 29 | } 30 | 31 | std::vector GetPath(const position& start, 32 | const std::unordered_map& parents) { 33 | std::vector result; 34 | 35 | position current = FinishPosition; 36 | while (current != start) { 37 | const position parent = parents.at(current); 38 | result.push_back(GetMoveSymbol(parent, current)); 39 | current = parent; 40 | } 41 | // Развернем result, так как собирали его с конца. 42 | std::reverse(result.begin(), result.end()); 43 | return result; 44 | } 45 | 46 | std::pair> SolvePuzzle8(const position& start) { 47 | // Запустим BFS, запоминая предков всех пройденных позиций. 48 | std::unordered_map parents; 49 | if (!BFS(start, parents)) { 50 | return std::make_pair(false, std::vector()); 51 | } 52 | return std::make_pair(true, GetPath(start, parents)); 53 | } 54 | -------------------------------------------------------------------------------- /Seminar7/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class DSU { 6 | public: 7 | explicit DSU(size_t size); 8 | 9 | int find(int element); 10 | void merge(int left, int right); 11 | void print() const; 12 | 13 | private: 14 | std::vector parent; 15 | std::vector rank; 16 | }; 17 | 18 | DSU::DSU(size_t size) : 19 | parent(size, -1), 20 | rank(size, 1) {} 21 | 22 | int DSU::find(int element) { 23 | if (parent[element] == -1) { 24 | return element; 25 | } 26 | return parent[element] = find(parent[element]); 27 | } 28 | 29 | void DSU::merge(int left, int right) { 30 | const int deputat_left = find(left); 31 | const int deputat_right = find(right); 32 | assert(deputat_left != deputat_right); 33 | if (rank[deputat_left] == rank[deputat_right]) { 34 | parent[deputat_right] = deputat_left; 35 | ++rank[deputat_left]; 36 | } else if(rank[deputat_left] > rank[deputat_right]) { 37 | parent[deputat_right] = deputat_left; 38 | } else { 39 | parent[deputat_left] = deputat_right; 40 | } 41 | } 42 | 43 | void DSU::print() const { 44 | for (const auto parent_element : parent) { 45 | std::cout << parent_element << " "; 46 | } 47 | std::cout << std::endl; 48 | } 49 | 50 | int main() { 51 | DSU dsu(7); 52 | dsu.print(); 53 | 54 | dsu.merge(0, 1); 55 | dsu.print(); 56 | dsu.merge(1, 2); 57 | dsu.print(); 58 | dsu.merge(3, 4); 59 | dsu.merge(0, 3); 60 | dsu.print(); 61 | std::cout << dsu.find(4) << std::endl; 62 | dsu.print(); 63 | dsu.merge(5, 6); 64 | dsu.print(); 65 | dsu.merge(4, 5); 66 | dsu.print(); 67 | 68 | std::cout << "Hello, World!" << std::endl; 69 | return 0; 70 | } -------------------------------------------------------------------------------- /Seminar6/position.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Stepan Matskevich on 2019-11-23. 3 | // 4 | 5 | #include "position.hpp" 6 | 7 | #include 8 | 9 | bool position::IsFinish() const { 10 | return operator==(FinishPosition); 11 | } 12 | 13 | std::vector position::Siblings() const { 14 | std::vector result; 15 | if (zero_place < 6) { 16 | position sibling = *this; 17 | std::swap(sibling.chips[zero_place], sibling.chips[zero_place + 3]); 18 | sibling.zero_place += 3; 19 | result.emplace_back(sibling); 20 | } 21 | if (zero_place >= 3) { 22 | position sibling = *this; 23 | std::swap(sibling.chips[zero_place], sibling.chips[zero_place - 3]); 24 | sibling.zero_place -= 3; 25 | result.emplace_back(sibling); 26 | } 27 | if (zero_place % 3 != 0) { 28 | position sibling = *this; 29 | std::swap(sibling.chips[zero_place], sibling.chips[zero_place - 1]); 30 | sibling.zero_place -= 1; 31 | result.emplace_back(sibling); 32 | } 33 | if (zero_place % 3 != 2) { 34 | position sibling = *this; 35 | std::swap(sibling.chips[zero_place], sibling.chips[zero_place + 1]); 36 | sibling.zero_place += 1; 37 | result.emplace_back(sibling); 38 | } 39 | return result; 40 | } 41 | 42 | bool position::operator==(const position& other) const { 43 | for (size_t i = 0; i < chips.size(); ++i ) { 44 | if (chips[i] != other.chips[i]) return false; 45 | } 46 | return true; 47 | } 48 | 49 | char GetMoveSymbol(const position& from, const position& to) { 50 | char zero_diff = to.zero_place - from.zero_place; 51 | switch (zero_diff) { 52 | case 1: 53 | return 'L'; // Ноль вправо -> фишка влево 54 | case -1: 55 | return 'R'; 56 | case 3: 57 | return 'U'; 58 | case -3: 59 | return 'D'; 60 | default: 61 | assert(false); 62 | } 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /Seminar5/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class BitsWriter { 5 | public: 6 | void WriteBit(bool bit); 7 | void WriteByte(unsigned char byte); 8 | 9 | std::vector GetResult(); 10 | 11 | private: 12 | std::vector buffer_; 13 | unsigned char accumulator_ = 0; 14 | int bits_count_ = 0; 15 | }; 16 | 17 | void BitsWriter::WriteBit(bool bit) { 18 | // Ставим бит в аккумулятор на нужное место 19 | accumulator_ |= static_cast(bit) << bits_count_; 20 | ++bits_count_; 21 | if (bits_count_ == 8) { 22 | bits_count_ = 0; 23 | buffer_.push_back(accumulator_); 24 | accumulator_ = 0; 25 | } 26 | } 27 | 28 | void BitsWriter::WriteByte(unsigned char byte) { 29 | if (bits_count_ == 0) { 30 | buffer_.push_back(byte); 31 | } else { 32 | accumulator_ |= byte << bits_count_; 33 | buffer_.push_back(accumulator_); 34 | accumulator_ = byte >> (8 - bits_count_); 35 | } 36 | } 37 | 38 | std::vector BitsWriter::GetResult() { 39 | if (bits_count_ != 0) { 40 | // Добавляем в буфер аккумулятор, если в нем что-то есть. 41 | buffer_.push_back(accumulator_); 42 | } 43 | buffer_.push_back(static_cast(bits_count_)); 44 | return std::move(buffer_); 45 | } 46 | 47 | int main() { 48 | BitsWriter bits_writer; 49 | 50 | bits_writer.WriteBit(true); 51 | bits_writer.WriteBit(false); 52 | bits_writer.WriteByte(0xFF); 53 | bits_writer.WriteBit(false); 54 | bits_writer.WriteBit(true); 55 | bits_writer.WriteBit(false); 56 | bits_writer.WriteBit(false); 57 | bits_writer.WriteBit(false); 58 | bits_writer.WriteBit(false); 59 | bits_writer.WriteByte(0xFE); 60 | bits_writer.WriteBit(true); 61 | bits_writer.WriteBit(false); 62 | std::vector result = 63 | std::move(bits_writer.GetResult()); 64 | 65 | for (unsigned char byte : result) { 66 | for (int i = 0; i < 8; ++i) { 67 | std::cout << ((byte >> i) & 1); 68 | } 69 | std::cout << " "; 70 | } 71 | return 0; 72 | } -------------------------------------------------------------------------------- /Seminar1/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Узел односвязного списка 5 | struct QueueNode { 6 | int value; 7 | QueueNode* next; 8 | }; 9 | 10 | class Queue { 11 | public: 12 | ~Queue(); 13 | 14 | // Проверка очереди на пустоту 15 | bool empty() const; 16 | // Добавление элемента 17 | void push(int value); 18 | // Извлечение 19 | int pop(); 20 | 21 | private: 22 | QueueNode* head = nullptr; 23 | QueueNode* tail = nullptr; 24 | }; 25 | 26 | Queue::~Queue() { 27 | while(head) { 28 | QueueNode* to_delete = head; 29 | head = head->next; 30 | delete to_delete; 31 | } 32 | } 33 | 34 | bool Queue::empty() const { 35 | // Оба указателя равны нулю одновреммено 36 | assert(((head == nullptr) && (tail == nullptr)) || 37 | ((head != nullptr) && (tail != nullptr))); 38 | 39 | return head == nullptr; 40 | } 41 | 42 | void Queue::push(int value) { 43 | if (empty()) { 44 | head = tail = new QueueNode{value, nullptr}; 45 | } else { 46 | tail->next = new QueueNode{value, nullptr}; 47 | tail = tail->next; 48 | } 49 | } 50 | 51 | int Queue::pop() { 52 | assert(!empty()); 53 | if (head == tail) { 54 | // Остался один 55 | int result = head->value; 56 | delete head; 57 | head = tail = nullptr; 58 | return result; 59 | } 60 | int result = head->value; 61 | QueueNode* next = head->next; 62 | delete head; 63 | head = next; 64 | return result; 65 | } 66 | 67 | int main() { 68 | int commands_count = 0; 69 | std::cin >> commands_count; 70 | 71 | Queue queue; 72 | for (int i = 0; i < commands_count; ++i) { 73 | int command = 0; 74 | int value = 0; 75 | std::cin >> command >> value; 76 | if (command == 3) { 77 | queue.push(value); 78 | } else if (command == 2) { 79 | if (queue.empty()) { 80 | if (value != -1) { 81 | std::cout << "NO"; 82 | return 0; 83 | } 84 | } else if (queue.pop() != value) { 85 | std::cout << "NO"; 86 | return 0; 87 | } 88 | } 89 | } 90 | std::cout << "YES"; 91 | return 0; 92 | } 93 | 94 | 95 | // Очередь с приоритетом для задач 2 96 | class PriorityQueue { 97 | public: 98 | bool empty() const; 99 | int top() const; 100 | int pop(); 101 | void push(int value); 102 | }; 103 | -------------------------------------------------------------------------------- /Seminar3/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Узел бинарного дерева 5 | struct TreeNode { 6 | explicit TreeNode(int _value) : value(_value) {} 7 | 8 | int value = 0; 9 | TreeNode* left = nullptr; 10 | TreeNode* right = nullptr; 11 | }; 12 | 13 | class Tree { 14 | public: 15 | ~Tree(); 16 | 17 | void Print() const; 18 | 19 | void Add(int value); 20 | 21 | private: 22 | TreeNode* root = nullptr; 23 | 24 | void print_subtree(TreeNode* node) const; 25 | 26 | void delete_subtree(TreeNode* node); 27 | }; 28 | 29 | Tree::~Tree() { 30 | delete_subtree(root); 31 | } 32 | 33 | void Tree::delete_subtree(TreeNode* node) { 34 | if (!node) return; 35 | delete_subtree(node->left); 36 | delete_subtree(node->right); 37 | delete node; 38 | } 39 | 40 | void Tree::Print() const { 41 | print_subtree(root); 42 | } 43 | 44 | void Tree::print_subtree(TreeNode* node) const { 45 | if (!node) return; 46 | print_subtree(node->left); 47 | std::cout << node->value << " "; 48 | print_subtree(node->right); 49 | } 50 | 51 | void Tree::Add(int value) { 52 | if (!root) { 53 | root = new TreeNode(value); 54 | } 55 | } 56 | 57 | // Поворот. Возвращает указатель на новый корень. 58 | TreeNode* RotateRight(TreeNode* root) { 59 | if (!root) { 60 | // Сигнализировать ошибку? 61 | return nullptr; 62 | } 63 | if (!root->left) { 64 | // Сигнализировать ошибку? 65 | return root; 66 | } 67 | TreeNode* new_root = root->left; 68 | root->left = new_root->right; 69 | new_root->right = root; 70 | return new_root; 71 | } 72 | 73 | // Узел декартова дерева. 74 | struct TreapNode { 75 | explicit TreapNode(int _value) : 76 | value(_value), priority(rand()) {} 77 | 78 | int value = 0; 79 | int priority = 0; 80 | TreapNode* left = nullptr; 81 | TreapNode* right = nullptr; 82 | }; 83 | 84 | class Treap { 85 | public: 86 | ~Treap(); 87 | 88 | private: 89 | TreapNode* root = nullptr; 90 | 91 | void delete_subtree(TreapNode* node); 92 | 93 | std::pair split(TreapNode* node, int x); 94 | }; 95 | 96 | std::pair split(TreapNode* node, int x) { 97 | if (!node) { 98 | return std::make_pair(nullptr, nullptr); 99 | } 100 | if (node->value < x) { 101 | const auto right_pair = split(node->right, x); 102 | node->right = right_pair.first; 103 | return std::make_pair(node, right_pair.second); 104 | } else { 105 | const auto left_pair = split(node->left, x); 106 | node->left = left_pair.second; 107 | return std::make_pair(left_pair.first, node); 108 | } 109 | } 110 | 111 | Treap::~Treap() { 112 | delete_subtree(root); 113 | } 114 | 115 | void Treap::delete_subtree(TreapNode* node) { 116 | if (!node) return; 117 | delete_subtree(node->left); 118 | delete_subtree(node->right); 119 | delete node; 120 | } 121 | 122 | int main() { 123 | srand(42); 124 | 125 | Tree tree; 126 | tree.Add(5); 127 | tree.Print(); 128 | return 0; 129 | } -------------------------------------------------------------------------------- /Seminar4/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | class HashTable { 7 | public: 8 | explicit HashTable(size_t initial_size); 9 | ~HashTable(); 10 | HashTable(const HashTable&) = delete; 11 | HashTable(HashTable&&) = delete; 12 | HashTable& operator=(const HashTable&) = delete; 13 | HashTable& operator=(HashTable&&) = delete; 14 | 15 | bool Has(const std::string& key) const; 16 | bool Add(const std::string& key); 17 | bool Remove(const std::string& key); 18 | 19 | private: 20 | struct HashTableNode { 21 | std::string key; 22 | HashTableNode* next = nullptr; 23 | 24 | HashTableNode(std::string key_) : key(std::move(key_)) {} 25 | }; 26 | std::vector table; 27 | }; 28 | 29 | HashTable::HashTable(size_t initial_size) : table(initial_size, nullptr) {} 30 | 31 | HashTable::~HashTable() { 32 | for (HashTableNode* head : table) { 33 | while (head) { 34 | HashTableNode* next = head->next; 35 | delete head; 36 | head = next; 37 | } 38 | } 39 | } 40 | 41 | bool HashTable::Has(const std::string& key) const { 42 | assert(!key.empty()); 43 | 44 | const size_t hash = key[0] % table.size(); 45 | for (auto head = table[hash]; head != nullptr; head = head->next) { 46 | if (head->key == key) { 47 | return true; 48 | } 49 | } 50 | return false; 51 | } 52 | 53 | bool HashTable::Add(const std::string& key) { 54 | assert(!key.empty()); 55 | 56 | const size_t hash = key[0] % table.size(); 57 | for (auto head = table[hash]; head != nullptr; head = head->next) { 58 | if (head->key == key) { 59 | return false; 60 | } 61 | } 62 | HashTableNode* new_node = new HashTableNode(key); 63 | new_node->next = table[hash]; 64 | table[hash] = new_node; 65 | return true; 66 | } 67 | 68 | bool HashTable::Remove(const std::string& key) { 69 | assert(!key.empty()); 70 | 71 | const size_t hash = key[0] % table.size(); 72 | HashTableNode*& head = table[hash]; 73 | if (!head) return false; 74 | if (head->key == key) { 75 | HashTableNode* to_delete = head; 76 | head = head->next; 77 | delete to_delete; 78 | return true; 79 | } 80 | HashTableNode* parent = head; 81 | for (; parent->next != nullptr; parent = parent->next) { 82 | if (parent->next->key == key) { 83 | HashTableNode* to_delete = parent->next; 84 | parent->next = parent->next->next; 85 | delete to_delete; 86 | return true; 87 | } 88 | } 89 | return false; 90 | } 91 | 92 | int main() { 93 | HashTable table(80); 94 | char command = ' '; 95 | std::string value; 96 | while (std::cin >> command >> value) { 97 | switch (command) { 98 | case '?': 99 | std::cout << (table.Has(value) ? "OK" : "FAIL") << std::endl; 100 | break; 101 | case '+': 102 | std::cout << (table.Add(value) ? "OK" : "FAIL") << std::endl; 103 | break; 104 | case '-': 105 | std::cout << (table.Remove(value) ? "OK" : "FAIL") << std::endl; 106 | break; 107 | } 108 | } 109 | return 0; 110 | } -------------------------------------------------------------------------------- /Seminar2/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct Point { 4 | int x; 5 | int y; 6 | 7 | bool operator<(const Point& other) const; 8 | }; 9 | 10 | bool Point::operator<(const Point& other) const { 11 | return y < other.y; 12 | } 13 | 14 | // Использует оператор < 15 | void BubbleSort(Point* arr, int size) { 16 | for(int i = 0; i < size - 1; ++i) { 17 | for(int j = 0; j < size - i - 1; ++j) { 18 | if(arr[j + 1] < arr[j]) { 19 | std::swap(arr[j], arr[j + 1]); 20 | } 21 | } 22 | } 23 | } 24 | 25 | // Функция сравнения по расстоянию до центра координат. 26 | bool CompareByDistToZero(const Point& first, const Point& second) { 27 | return (first.x * first.x + first.y * first.y) < 28 | (second.x * second.x + second.y * second.y); 29 | } 30 | 31 | // Использует функцию сравнения 32 | void BubbleSort(Point* arr, int size, bool (*compare)(const Point&, const Point&)) { 33 | for(int i = 0; i < size - 1; ++i) { 34 | for(int j = 0; j < size - i - 1; ++j) { 35 | if(compare(arr[j + 1], arr[j])) { 36 | std::swap(arr[j], arr[j + 1]); 37 | } 38 | } 39 | } 40 | } 41 | 42 | // Функтор, сравнивающий точки по расстоянию до center. 43 | class ComparerByDistToCenter { 44 | public: 45 | explicit ComparerByDistToCenter(const Point& center) : center_(center) {} 46 | 47 | bool operator()(const Point& first, const Point& second) const; 48 | 49 | private: 50 | Point center_; 51 | }; 52 | 53 | bool ComparerByDistToCenter::operator()(const Point& first, const Point& second) const { 54 | const int first_diff_x = first.x - center_.x; 55 | const int first_diff_y = first.y - center_.y; 56 | const int second_diff_x = second.x - center_.x; 57 | const int second_diff_y = second.y - center_.y; 58 | 59 | return (first_diff_x * first_diff_x + first_diff_y * first_diff_y) < 60 | (second_diff_x * second_diff_x + second_diff_y * second_diff_y); 61 | } 62 | 63 | // Использует шаблонное нечто, имеющее () 64 | template 65 | void BubbleSortT(Point* arr, int size, const TCompare& compare) { 66 | for(int i = 0; i < size - 1; ++i) { 67 | for(int j = 0; j < size - i - 1; ++j) { 68 | if(compare(arr[j + 1], arr[j])) { 69 | std::swap(arr[j], arr[j + 1]); 70 | } 71 | } 72 | } 73 | } 74 | 75 | 76 | int main() { 77 | Point arr[]{Point{3, 5}, Point{0, 0}, Point{1, 2}, Point{2, 8}, Point{4, 2}}; 78 | // Сортировка с помощью оператора < 79 | // BubbleSort(arr, 5); 80 | 81 | // Сортировка с помощью функции сравнения 82 | // BubbleSort(arr, 5, CompareByDistToZero); 83 | 84 | // Сортировка с помощью функции сравнения шаблонной функцией 85 | // BubbleSortT(arr, 5, CompareByDistToZero); 86 | 87 | // Сортировка с помощью функтора шаблонной функцией 88 | // BubbleSortT(arr, 5, ComparerByDistToCenter(Point{3, 3})); 89 | 90 | const Point center{3, 3}; 91 | BubbleSortT(arr, 5, [¢er](const Point& first, const Point& second) { 92 | const int first_diff_x = first.x - center.x; 93 | const int first_diff_y = first.y - center.y; 94 | const int second_diff_x = second.x - center.x; 95 | const int second_diff_y = second.y - center.y; 96 | 97 | return (first_diff_x * first_diff_x + first_diff_y * first_diff_y) < 98 | (second_diff_x * second_diff_x + second_diff_y * second_diff_y); 99 | }); 100 | 101 | for(int i = 0; i < 5; ++i) { 102 | std::cout << arr[i].x << " " << arr[i].y << std::endl; 103 | } 104 | return 0; 105 | } -------------------------------------------------------------------------------- /Seminar8/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Node { 6 | std::map> go; 7 | bool is_terminal = false; 8 | }; 9 | 10 | class Trie { 11 | public: 12 | Trie(); 13 | Trie(const Trie&) = delete; 14 | Trie(Trie&&) = delete; 15 | Trie& operator=(const Trie&) = delete; 16 | Trie& operator=(Trie&&) = delete; 17 | ~Trie() = default; 18 | 19 | bool Has(const std::string& key) const; 20 | bool Add(const std::string& key); 21 | bool Remove(const std::string& key); 22 | void Print() const; 23 | 24 | private: 25 | std::shared_ptr root; 26 | 27 | static void print(const std::shared_ptr& node, const std::string& current); 28 | // Возвращает пару bool: первый - о наличии строки 29 | // второй - о единственности узла и необходимости его удалить. 30 | static std::pair remove( 31 | std::shared_ptr& node, const std::string& key, int current_index); 32 | }; 33 | 34 | Trie::Trie() { 35 | root = std::make_shared(); 36 | } 37 | 38 | bool Trie::Has(const std::string& key) const { 39 | std::shared_ptr current = root; 40 | for (char symbol : key) { 41 | auto next = current->go.find(symbol); 42 | if (next == current->go.end()) return false; 43 | current = next->second; 44 | } 45 | return current->is_terminal; 46 | } 47 | 48 | bool Trie::Add(const std::string& key) { 49 | std::shared_ptr current = root; 50 | for (char symbol : key) { 51 | auto next = current->go.find(symbol); 52 | if (next == current->go.end()) { 53 | current = current->go[symbol] = std::make_shared(); 54 | } else { 55 | current = next->second; 56 | } 57 | } 58 | // Если терминальная, значит, строка уже есть. 59 | if (current->is_terminal) return false; 60 | current->is_terminal = true; 61 | return true; 62 | } 63 | 64 | bool Trie::Remove(const std::string& key) { 65 | return remove(root, key, 0).first; 66 | } 67 | 68 | std::pair Trie::remove( 69 | std::shared_ptr& node, const std::string& key, int current_index) { 70 | if (current_index == key.length()) { 71 | if (!node->is_terminal) return std::make_pair(false, false); 72 | node->is_terminal = false; 73 | return std::make_pair(true, node->go.empty()); 74 | } 75 | 76 | auto next = node->go.find(key[current_index]); 77 | if (next == node->go.end()) { 78 | return std::make_pair(false, false); 79 | } 80 | 81 | auto result = remove(next->second, key, current_index + 1); 82 | 83 | if (!result.first) { // Не нашли 84 | return result; 85 | } 86 | if (!result.second) { // Не нужно удалить ссылку на дочерний 87 | return result; 88 | } 89 | node->go.erase(key[current_index]); 90 | return std::make_pair(true, !node->is_terminal && node->go.empty()); 91 | } 92 | 93 | void Trie::Print() const { 94 | print(root, ""); 95 | } 96 | 97 | void Trie::print(const std::shared_ptr& node, const std::string& current) { 98 | if (node->is_terminal) { 99 | std::cout << current << std::endl; 100 | } 101 | for (const auto go : node->go) { 102 | print(go.second, current + go.first); 103 | } 104 | } 105 | 106 | //int main() { 107 | // Trie trie; 108 | // trie.Add("aaa"); 109 | // trie.Add("aa"); 110 | // trie.Remove("aaa"); 111 | // trie.Print(); 112 | // return 0; 113 | //} 114 | 115 | int main() { 116 | Trie trie; 117 | char command = 0; 118 | std::string key; 119 | while (std::cin >> command >> key) { 120 | switch (command) { 121 | case '+': 122 | std::cout << (trie.Add(key) ? "OK" : "FAIL") << std::endl; 123 | break; 124 | case '-': 125 | std::cout << (trie.Remove(key) ? "OK" : "FAIL") << std::endl; 126 | break; 127 | case '?': 128 | std::cout << (trie.Has(key) ? "OK" : "FAIL") << std::endl; 129 | break; 130 | } 131 | } 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /Seminar9/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct Point { 7 | double lon; 8 | double lat; 9 | }; 10 | 11 | struct Bbox { 12 | double left; 13 | double bottom; 14 | double right; 15 | double top; 16 | 17 | bool Contains(const Point& point) const { 18 | return left <= point.lon && bottom <= point.lat && 19 | point.lon < right && point.lat < top; 20 | } 21 | }; 22 | 23 | class KDTree { 24 | public: 25 | explicit KDTree(std::vector& points); 26 | 27 | int CountPointsInBbox(const Bbox& bbox); 28 | 29 | private: 30 | struct KDNode { 31 | Point median; 32 | std::unique_ptr left; 33 | std::unique_ptr right; 34 | 35 | explicit KDNode(const Point& median_) : median(median_) {} 36 | }; 37 | 38 | std::unique_ptr root; 39 | 40 | static std::unique_ptr BuildTree( 41 | std::vector& points, size_t left, size_t right, int depth); 42 | static int CountPointsInBbox( 43 | const Bbox& bbox, const std::unique_ptr& node, int depth); 44 | }; 45 | 46 | KDTree::KDTree(std::vector& points) { 47 | root = BuildTree(points, 0, points.size(), 0); 48 | } 49 | 50 | namespace { 51 | template 52 | size_t Partition( 53 | std::vector& points, size_t left, size_t right, comparator cmp) { 54 | int pivot_pos = static_cast(right) - 1; 55 | int i = static_cast(left), j = pivot_pos - 1; 56 | while (i <= j) { 57 | for (; cmp(points[i], points[pivot_pos]); ++i) {} 58 | for (; j >= i && !cmp(points[j], points[pivot_pos]); --j) {} 59 | if (i < j) std::swap(points[i], points[j]); 60 | } 61 | std::swap(points[i], points[pivot_pos]); 62 | return static_cast(i); 63 | } 64 | 65 | void LocateMedian( 66 | std::vector& points, size_t left, size_t right, int depth) { 67 | const size_t med = (left + right) / 2; 68 | 69 | while (true) { 70 | size_t pivot_pos = Partition(points, left, right, 71 | [depth](const Point& first, const Point& second){ 72 | if(depth % 2 == 0) { 73 | return first.lon < second.lon; 74 | } else { 75 | return first.lat < second.lat; 76 | } 77 | }); 78 | if (pivot_pos == med) return; 79 | if (pivot_pos < med) left = pivot_pos + 1; 80 | else right = pivot_pos; 81 | } 82 | } 83 | } // unnamed namespace 84 | 85 | std::unique_ptr KDTree::BuildTree( 86 | std::vector& points, size_t left, size_t right, int depth) { 87 | assert(left < right); 88 | const size_t med = (left + right) / 2; 89 | LocateMedian(points, left, right, depth); 90 | auto node = std::make_unique(points[med]); 91 | 92 | if (med > left) { 93 | node->left = BuildTree(points, left, med, depth + 1); 94 | } 95 | if (med + 1 < right) { 96 | node->right = BuildTree(points, med + 1, right, depth + 1); 97 | } 98 | return node; 99 | } 100 | 101 | int KDTree::CountPointsInBbox( 102 | const Bbox& bbox, const std::unique_ptr& node, int depth) { 103 | int count = 0; 104 | if (bbox.Contains(node->median)) { 105 | ++count; 106 | } 107 | if (depth % 2 == 0) { 108 | if (node->left && bbox.left <= node->median.lon) { 109 | count += CountPointsInBbox(bbox, node->left, depth + 1); 110 | } 111 | if (node->right && node->median.lon < bbox.right) { 112 | count += CountPointsInBbox(bbox, node->right, depth + 1); 113 | } 114 | } else { 115 | if (node->left && bbox.bottom <= node->median.lat) { 116 | count += CountPointsInBbox(bbox, node->left, depth + 1); 117 | } 118 | if (node->right && node->median.lat < bbox.top) { 119 | count += CountPointsInBbox(bbox, node->right, depth + 1); 120 | } 121 | } 122 | return count; 123 | } 124 | 125 | int KDTree::CountPointsInBbox(const Bbox& bbox) { 126 | if (!root) return 0; 127 | return CountPointsInBbox(bbox, root, 0); 128 | } 129 | 130 | int main() { 131 | std::vector points{{1., 3.}, {4., 1.}, {0., 3.}, 132 | {1., 1.}, {2., 2.}, {1., 5.}, 133 | {4., 5.}, {3., 4.}, {3., 0.}}; 134 | KDTree tree(points); 135 | 136 | std::cout << tree.CountPointsInBbox({0.0, 0.0, 0.0, 0.0}) << std::endl; 137 | std::cout << tree.CountPointsInBbox({0.0, 0.0, 2.0, 2.0}) << std::endl; 138 | std::cout << tree.CountPointsInBbox({-.5, .5, 2.5, 3.5}) << std::endl; 139 | std::cout << tree.CountPointsInBbox({0.0, 1.0, 3.0, 4.0}) << std::endl; 140 | return 0; 141 | } --------------------------------------------------------------------------------