From 8dc1e44ceb3ed1a7cc8704c4a5ea6d943374b712 Mon Sep 17 00:00:00 2001 From: Me-Phew Date: Wed, 13 Nov 2024 21:47:49 +0100 Subject: [PATCH 1/2] feat: implement merge sort algorithm --- CMakeLists.txt | 4 +- src/app/app.cpp | 126 ++++++++++++++++++++++++++++++ src/app/app.hpp | 68 ++++++++++++++++ src/main.cpp | 14 +++- src/main.h | 10 --- src/merge_sorter/merge_sorter.cpp | 82 +++++++++++++++++++ src/merge_sorter/merge_sorter.hpp | 19 +++++ 7 files changed, 309 insertions(+), 14 deletions(-) create mode 100644 src/app/app.cpp create mode 100644 src/app/app.hpp delete mode 100644 src/main.h create mode 100644 src/merge_sorter/merge_sorter.cpp create mode 100644 src/merge_sorter/merge_sorter.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 31f554a..66cc881 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,9 @@ cmake_minimum_required(VERSION 3.10) project(MergeSort) -set(SOURCES src/main.cpp) +include_directories(src/app src/merge_sorter) + +set(SOURCES src/main.cpp src/app/app.cpp src/merge_sorter/merge_sorter.cpp) add_executable(MergeSort ${SOURCES}) diff --git a/src/app/app.cpp b/src/app/app.cpp new file mode 100644 index 0000000..68b61da --- /dev/null +++ b/src/app/app.cpp @@ -0,0 +1,126 @@ +/** + * @file app.cpp + * @author Mateusz Basiaga (basmateusz@wp.pl) + * @brief + * @date 2024-11-13 + * + * @copyright Copyright (c) 2024 + * + */ + +#ifdef _WIN32 +#include +#endif + +#include "app.hpp" +#include "../merge_sorter/merge_sorter.hpp" + +std::istream& operator>>(std::istream& iStream, MenuOption& menuOption) { + int num; + iStream >> num; + menuOption = static_cast(num); + + return iStream; +} + +std::vector App::array; + +int App::mainMenu() { + while (true) { + std::cout << "MENU:\n\n"; + + std::cout << "---ZARZĄDZANIE ELEMENTAMI LISTY---\n"; + std::cout << "1. Dodaj element\n\n"; + + std::cout << "---ZARZĄDZANIE LISTĄ---\n"; + std::cout << "2. Wyświetl zawrtość\n"; + std::cout << "3. Posortuj\n"; + std::cout << "4. Wyczyść\n\n"; + + std::cout << "---OPCJE---\n"; + std::cout << "5. Wyjdź\n\n"; + + std::cout << "Wybierz działanie: "; + + MenuOption selectedOption; + + std::cin >> selectedOption; + + if (selectedOption > EXIT) { + std::cout << "Nieprawidłowa opcja, spróbuj ponownie\n\n"; + continue; + } + + std::cout << std::endl; + + switch (selectedOption) { + case INSERT_ITEM: + handleInsertItem(); + break; + case DISPLAY_ARRAY: + handleDisplayArray(); + break; + case SORT_ARRAY: + handleSortArray(); + break; + case CLEAR_ARRAY: + handleClearArray(); + break; + case EXIT: { + return handleExit(); + } + default: + std::cout << "Nieprawidłowa opcja, spróbuj ponownie\n"; + } + + std::cout << "\n"; + } +} + + +int App::run() { +#ifdef _WIN32 + // enable utf-8 printing on windows + SetConsoleOutputCP(CP_UTF8); +#endif + + int exitCode = mainMenu(); + return exitCode; +} + +void App::handleInsertItem() { + std::cout << "Podaj wartość: "; + int value; + std::cin >> value; + + array.push_back(value); +} + +void App::handleDisplayArray() { + std::cout << "["; + + for (auto it = array.begin(); it != array.end(); ++it) { + std::cout << *it; + + if (it != array.end() - 1) { + std::cout << ", "; + } + } + + std::cout << "]\n"; +} + +void App::handleClearArray() { + array.clear(); + std::cout << "Wyczyszczono listę\n"; +} + +void App::handleSortArray() { + array = MergeSorter::sortArray(array); + std::cout << "Posortowano listę\n"; +} + +int App::handleExit() { + std::cout << "Dziękujemy za korzystanie z programu\n"; + return 0; +} diff --git a/src/app/app.hpp b/src/app/app.hpp new file mode 100644 index 0000000..4a5f769 --- /dev/null +++ b/src/app/app.hpp @@ -0,0 +1,68 @@ +/** + * @file app.hpp + * @author Mateusz Basiaga (basmateusz@wp.pl) + * @brief + * @date 2024-11-13 + * + * @copyright Copyright (c) 2024 + * + */ + +#ifndef APP_HPP +#define APP_HPP + +#include +#include + + /// @brief Wyliczenie opcji dostępnych w menu. + /// Definiuje różne operacje, które użytkownik może wybrać w aplikacji. +enum MenuOption { + INSERT_ITEM = 1, + + DISPLAY_ARRAY, + SORT_ARRAY, + CLEAR_ARRAY, + + EXIT ///< Zakończenie działania aplikacji. +}; + +/// @brief Przeciążenie operatora >> do wyboru opcji menu. +/// @param iStream Strumień wejściowy. +/// @param menuOption Opcja menu, którą należy ustawić. +/// @return Referencja do strumienia wejściowego. +std::istream& operator>>(std::istream& iStream, MenuOption& menuOption); + +/// @brief Klasa reprezentująca aplikację obsługującą listę. +/// Umożliwia operacje takie jak dodawanie, usuwanie i wyświetlanie elementów oraz sortowanie listy poprzez menu. +class App { +private: + static std::vector array; + + App() = delete; + App(const App&) = delete; + App& operator=(const App&) = delete; + + /// @brief Wyświetla główne menu aplikacji i zwraca wybraną opcję. + /// @return Wybrana opcja menu. + static int mainMenu(); + + static void handleInsertItem(); + + static void handleDisplayArray(); + + static void handleClearArray(); + + static void handleSortArray(); + + /// @brief Obsługuje zakończenie działania aplikacji. + /// @return Kod wyjścia z aplikacji. + static int handleExit(); + +public: + /// @brief Uruchamia aplikację. + /// Wyświetla menu i pozwala użytkownikowi wykonywać operacje na liście. + /// @return Kod zakończenia aplikacji. + static int run(); +}; + +#endif /* APP_HPP */ diff --git a/src/main.cpp b/src/main.cpp index 6091f13..022832d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,15 @@ -#include +/** + * @file main.cpp + * @author Mateusz Basiaga (basmateusz@wp.pl) + * @brief + * @date 2024-11-13 + * + * @copyright Copyright (c) 2024 + * + */ -#include "main.h" +#include "app/app.hpp" int main() { - std::cout << "Hello world!"; + return App::run(); } diff --git a/src/main.h b/src/main.h deleted file mode 100644 index f19df58..0000000 --- a/src/main.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef MAIN_H -#define MAIN_H - -/// @brief Doxygen comment example. -class List { - -}; - - -#endif /* MAIN_H */ diff --git a/src/merge_sorter/merge_sorter.cpp b/src/merge_sorter/merge_sorter.cpp new file mode 100644 index 0000000..3be230c --- /dev/null +++ b/src/merge_sorter/merge_sorter.cpp @@ -0,0 +1,82 @@ +/** + * @file merge_sorter.cpp + * @author Mateusz Basiaga (basmateusz@wp.pl) + * @brief + * @date 2024-11-13 + * + * @copyright Copyright (c) 2024 + * + */ + +#include + +#include "merge_sorter.hpp" + +std::vector MergeSorter::merge(std::vector arr, int left, int mid, int right) { + + int leftSize = mid - left + 1; + int rightSize = right - mid; + + std::vector L(leftSize); + std::vector M(rightSize); + + // Wypełnienie tablicy L danymi z lewej części głównej tablicy + for (int i = 0; i < leftSize; i++) + L[i] = arr[left + i]; + + // Wypełnienie tablicy M danymi z prawej części głównej tablicy + for (int j = 0; j < rightSize; j++) + M[j] = arr[mid + 1 + j]; + + // Pozostawienie bieżących indeksów w podtablicach oraz w głównej tablicy + int i = 0, j = 0, k = left; + + // Dopóki nie osiągniemy końca jednej z podtablic L lub M, + // wybieramy mniejszy element z L lub M i umieszcamy go we właściwej pozycji w A[left..right] + while (i < leftSize && j < rightSize) { + if (L[i] <= M[j]) { + arr[k] = L[i]; + i++; + } else { + arr[k] = M[j]; + j++; + } + k++; + } + + // Gdy skończą się elementy w jednej z podtablic L lub M, + // przenosimy pozostałe elementy do A[left..right] + while (i < leftSize) { + arr[k] = L[i]; + i++; + k++; + } + + while (j < rightSize) { + arr[k] = M[j]; + j++; + k++; + } + + return arr; +} + +std::vector MergeSorter::mergeSort(std::vector& arr, int left, int right) { + if (left < right) { + // mid jest punktem, w którym tablica jest dzielona na dwie podtablice + int mid = left + (right - left) / 2; + + // Wywołujemy rekurencyjnie sortowanie dla lewej i prawej części + mergeSort(arr, left, mid); + mergeSort(arr, mid + 1, right); + + // Scalamy posortowane podtablice + arr = merge(arr, left, mid, right); + } + + return arr; +} + +std::vector MergeSorter::sortArray(std::vector& arr) { + return mergeSort(arr, 0, (int)arr.size() - 1); +} diff --git a/src/merge_sorter/merge_sorter.hpp b/src/merge_sorter/merge_sorter.hpp new file mode 100644 index 0000000..c5e7969 --- /dev/null +++ b/src/merge_sorter/merge_sorter.hpp @@ -0,0 +1,19 @@ +#ifndef MERGE_SORTER_HPP +#define MERGE_SORTER_HPP + +#include + +class MergeSorter { +private: + MergeSorter() = delete; + MergeSorter(const MergeSorter&) = delete; + MergeSorter& operator=(const MergeSorter&) = delete; + + static std::vector MergeSorter::merge(std::vector arr, int left, int mid, int right); + static std::vector MergeSorter::mergeSort(std::vector& arr, int left, int right); + +public: + static std::vector sortArray(std::vector& arr); +}; + +#endif /* MERGE_SORTER_HPP */ From b6a38f99414834ac06d4a4bf2f86a9d0313d0726 Mon Sep 17 00:00:00 2001 From: Me-Phew Date: Wed, 13 Nov 2024 21:51:56 +0100 Subject: [PATCH 2/2] refactor: remove extra qualifications --- src/merge_sorter/merge_sorter.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/merge_sorter/merge_sorter.hpp b/src/merge_sorter/merge_sorter.hpp index c5e7969..250d880 100644 --- a/src/merge_sorter/merge_sorter.hpp +++ b/src/merge_sorter/merge_sorter.hpp @@ -9,8 +9,8 @@ class MergeSorter { MergeSorter(const MergeSorter&) = delete; MergeSorter& operator=(const MergeSorter&) = delete; - static std::vector MergeSorter::merge(std::vector arr, int left, int mid, int right); - static std::vector MergeSorter::mergeSort(std::vector& arr, int left, int right); + static std::vector merge(std::vector arr, int left, int mid, int right); + static std::vector mergeSort(std::vector& arr, int left, int right); public: static std::vector sortArray(std::vector& arr);