Advertisement
MaksNew

SLList.cpp

Feb 28th, 2021
294
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.59 KB | None | 0 0
  1. #include "SLList.h"
  2. #include <iostream>
  3. #include <regex>
  4. #include <sstream>
  5. #include <filesystem>
  6. #include <fstream>
  7.  
  8. namespace SLList {
  9.     using namespace std;
  10.  
  11.     template<typename T>
  12.     class SinglyLinkedList
  13.     {
  14.     public:
  15.         SinglyLinkedList();
  16.         SinglyLinkedList(const SinglyLinkedList& other);
  17.         ~SinglyLinkedList();
  18.         void push_back(T data);
  19.         void push_front(T data);
  20.         void pop_front();
  21.         void clear();
  22.         void build_empty(size_t sizeOfList);
  23.         void insert(T data, int index);
  24.         void removeAt(int index);
  25.         void pop_back();
  26.         int getSize() { return size; }
  27.         T operator[] (const int index);
  28.     private:
  29.         template<typename T>
  30.         class Node
  31.         {
  32.         public:
  33.             Node* pNext;
  34.             T data;
  35.             Node(T data = T(), Node* pNext = nullptr)
  36.             {
  37.                 this->data = data;
  38.                 this->pNext = pNext;
  39.             }
  40.         };
  41.         Node<T>* head;
  42.         size_t size;
  43.     };
  44.  
  45.     template<typename T>
  46.     SinglyLinkedList<T>::SinglyLinkedList()
  47.     {
  48.         size = 0;
  49.         head = nullptr;
  50.     }
  51.  
  52.     template<typename T>
  53.     SinglyLinkedList<T>::SinglyLinkedList(const SinglyLinkedList& other) : SinglyLinkedList()
  54.     {
  55.         Node<T>* current = other.head;
  56.         while (current != nullptr)
  57.         {
  58.             push_back(current->data);
  59.             current = current->pNext;
  60.         }
  61.     }
  62.  
  63.     template<typename T>
  64.     SinglyLinkedList<T>::~SinglyLinkedList()
  65.     {
  66.         clear();
  67.     }
  68.  
  69.     template<typename T>
  70.     void SinglyLinkedList<T>::push_back(T data)
  71.     {
  72.         if (head == nullptr)
  73.         {
  74.             head = new Node<T>(data);
  75.         }
  76.         else
  77.         {
  78.             Node<T>* current = this->head;
  79.             while (current->pNext != nullptr)
  80.             {
  81.                 current = current->pNext;
  82.             }
  83.             current->pNext = new Node<T>(data);
  84.         }
  85.         size++;
  86.     }
  87.  
  88.     template<typename T>
  89.     void SinglyLinkedList<T>::pop_front()
  90.     {
  91.         Node<T>* temp = head;
  92.         head = head->pNext;
  93.         delete temp;
  94.         size--;
  95.     }
  96.  
  97.     template<typename T>
  98.     T SinglyLinkedList<T>::operator[](const int index)
  99.     {
  100.         size_t counter = 0;
  101.         Node<T>* current = this->head;
  102.         while (current != nullptr)
  103.         {
  104.             if (counter == index)
  105.             {
  106.                 return current->data;
  107.             }
  108.             ++counter;
  109.             current = current->pNext;
  110.         }
  111.     }
  112.  
  113.     template<typename T>
  114.     void SinglyLinkedList<T>::clear()
  115.     {
  116.         while (size)
  117.         {
  118.             pop_front();
  119.         }
  120.     }
  121.  
  122.     template<typename T>
  123.     void SinglyLinkedList<T>::build_empty(size_t sizeOfList)
  124.     {
  125.         for (size_t i = 0; i < sizeOfList; ++i)
  126.         {
  127.             push_back(T());
  128.         }
  129.     }
  130.  
  131.     template<typename T>
  132.     void SinglyLinkedList<T>::push_front(T data)
  133.     {
  134.         head = new Node<T>(data, head);
  135.         size++;
  136.     }
  137.  
  138.     template<typename T>
  139.     void SinglyLinkedList<T>::insert(T data, int index)
  140.     {
  141.         if (index == 0)
  142.         {
  143.             push_front(data);
  144.         }
  145.         else
  146.         {
  147.             Node<T>* previous = this->head;
  148.             for (size_t i = 0; i < index - 1; ++i)
  149.             {
  150.                 previous = previous->pNext;
  151.             }
  152.             Node<T>* newNode = new Node<T>(data, previous->pNext);
  153.             previous->pNext = newNode;
  154.             ++size;
  155.         }
  156.     }
  157.  
  158.     template<typename T>
  159.     void SinglyLinkedList<T>::removeAt(int index)
  160.     {
  161.         if (index == 0)
  162.         {
  163.             pop_front();
  164.         }
  165.         else
  166.         {
  167.             Node<T>* previous = this->head;
  168.             for (size_t i = 0; i < index - 1; ++i)
  169.             {
  170.                 previous = previous->pNext;
  171.             }
  172.             Node<T>* temp = previous->pNext;
  173.             previous->pNext = temp->pNext;
  174.             delete temp;
  175.             size--;
  176.         }
  177.     }
  178.  
  179.     template<typename T>
  180.     void SinglyLinkedList<T>::pop_back()
  181.     {
  182.         removeAt(size - 1);
  183.     }
  184.  
  185.     template<typename T>
  186.     void print(SinglyLinkedList<T> list)
  187.     {
  188.         cout << endl << "№\t" << "элемент" << endl;
  189.         for (size_t i = 0; i < list.getSize(); ++i)
  190.         {
  191.             cout << i + 1 << "\t" << list[i] << endl;
  192.         }
  193.         cout << endl;
  194.     }
  195.  
  196.     template<typename T>
  197.     unsigned short allEntryOfElement(T element, SinglyLinkedList<T> list)
  198.     {
  199.         unsigned short counter = 0;
  200.         for (size_t i = 0; i < list.getSize(); ++i)
  201.         {
  202.             if (element == list[i])
  203.                 counter++;
  204.         }
  205.         return counter;
  206.     }
  207.  
  208.     bool isFileCorrect(string path)
  209.     {
  210.         string inputline;
  211.         regex regular("^(\\d+\\s*)+$");
  212.         fstream fin(path, ios_base::in);
  213.         bool isCorrect = true;
  214.         while (!fin.eof() && isCorrect)
  215.         {
  216.             getline(fin, inputline);
  217.             if (!(regex_match(inputline.c_str(), regular)))
  218.                 isCorrect = false;
  219.         }
  220.         fin.close();
  221.         return isCorrect;
  222.     }
  223.  
  224.     string readFilePath(bool flag)
  225.     {
  226.         string path;
  227.         bool isIncorrect;
  228.         do
  229.         {
  230.             isIncorrect = false;
  231.             cout << "Введите абсолютный путь к файлу: " << endl;
  232.             cin >> path;
  233.             if (!filesystem::exists(path))
  234.             {
  235.                 cout << "Файл не найден. Проверьте введённый путь." << endl;
  236.                 isIncorrect = true;
  237.             }
  238.             else
  239.             {
  240.                 if (flag && !isFileCorrect(path))
  241.                 {
  242.                     cout << "Ошибка при чтении файла! Проверьте данные и попробуйте ещё раз!" << endl;
  243.                     isIncorrect = true;
  244.                 }
  245.             }
  246.  
  247.         } while (isIncorrect);
  248.         return path;
  249.     }
  250.  
  251.     template<typename T>
  252.     void getListFromFile(SinglyLinkedList<T>& list)
  253.     {
  254.         bool flag = true;
  255.         string path = readFilePath(flag);
  256.         string inputline;
  257.         cmatch res;
  258.         regex reg("(\\d+)\\s*");
  259.         fstream fin(path, std::ios_base::in);
  260.         while (!fin.eof())
  261.         {
  262.             getline(fin, inputline);
  263.             auto inputline_begin = sregex_iterator(inputline.begin(), inputline.end(), reg);
  264.             auto inputline_end = sregex_iterator();
  265.             for (auto i = inputline_begin; i != inputline_end; ++i)
  266.             {
  267.                 list.push_back(stoi((*i).str()));
  268.             }
  269.         }
  270.         fin.close();
  271.     }
  272.  
  273.     int readElement(int data)
  274.     {
  275.         string inputLine;
  276.         bool isIncorrect;
  277.         do
  278.         {
  279.             isIncorrect = false;
  280.             try
  281.             {
  282.                 cin >> inputLine;
  283.                 data = stoi(inputLine);
  284.             }
  285.             catch (...)
  286.             {
  287.                 isIncorrect = true;
  288.                 cout << "Введите целое число!" << endl;
  289.             }
  290.         } while (isIncorrect);
  291.         return data;
  292.     }
  293.  
  294.     void getListElementFromConsole(SinglyLinkedList<int>& list)
  295.     {
  296.         int data = 0;
  297.         cout << "Введите элемент списка: \n";
  298.         data = readElement(data);
  299.         list.push_back(data);
  300.     }
  301.  
  302.     int getMainMenuItem(bool item5)
  303.     {
  304.         bool isIncorrect;
  305.         string inputLine;
  306.         int item = 0;
  307.         do
  308.         {
  309.             isIncorrect = false;
  310.             try
  311.             {
  312.                 cin >> inputLine;
  313.                 item = stoi(inputLine);
  314.             }
  315.             catch (...)
  316.             {
  317.                 isIncorrect = true;
  318.                 cout << "Введите целое число!" << endl;
  319.             }
  320.             if (!item5 && (item != 1) && (item != 2) && (item != 3) && !isIncorrect)
  321.             {
  322.                 cout << "Выберете один из пунктов меню!\n";
  323.                 isIncorrect = true;
  324.             }
  325.             if (item5 && (item != 1) && (item != 2) && (item != 3) && (item != 4) && (item != 5) && !isIncorrect)
  326.             {
  327.                 cout << "Выберете один из пунктов меню!\n";
  328.                 isIncorrect = true;
  329.             }
  330.         } while (isIncorrect);
  331.         return item;
  332.     }
  333.  
  334.     int readSizeOfEmptyList()
  335.     {
  336.         bool isIncorrect;
  337.         string inputLine;
  338.         int size;
  339.         do
  340.         {
  341.             isIncorrect = false;
  342.             try
  343.             {
  344.                 cin >> inputLine;
  345.                 size = stoi(inputLine);
  346.             }
  347.             catch (...)
  348.             {
  349.                 isIncorrect = true;
  350.                 cout << "Введите целое число!" << endl;
  351.             }
  352.             if (!isIncorrect && size < 1 && size > 2000000)
  353.             {
  354.                 cout << "Введите положительное число до 2*10^6!\n";
  355.                 isIncorrect = true;
  356.             }
  357.         } while (isIncorrect);
  358.         return size;
  359.     }
  360.  
  361.     size_t readDeletableElementIndex(size_t index, SinglyLinkedList<int>& list)
  362.     {
  363.         bool isIncorrect;
  364.         string inputLine;
  365.         do
  366.         {
  367.             isIncorrect = false;
  368.             try
  369.             {
  370.                 cin >> inputLine;
  371.                 index = stoi(inputLine);
  372.             }
  373.             catch (...)
  374.             {
  375.                 isIncorrect = true;
  376.                 cout << "Введите целое число!" << endl;
  377.             }
  378.             if (!isIncorrect && index + 1 < list.getSize() && index + 1 > list.getSize())
  379.             {
  380.                 cout << "Введите индекс в преедлах размера списка!\n";
  381.                 isIncorrect = true;
  382.             }
  383.         } while (isIncorrect);
  384.         return index - 1;
  385.     }
  386.  
  387.     string readFilePath()
  388.     {
  389.         string path;
  390.         bool isIncorrect;
  391.         isIncorrect = true;
  392.         do
  393.         {
  394.             cout << "Введите абсолютный путь к файлу: " << endl;
  395.             cin >> path;
  396.             if (!std::filesystem::exists(path))
  397.                 cout << "Файл не найден. Проверьте введённый путь." << endl;
  398.             else
  399.                 isIncorrect = false;
  400.         } while (isIncorrect);
  401.         return path;
  402.     }
  403.  
  404.     void saveList(SinglyLinkedList<int>& list)
  405.     {
  406.         ofstream fout;
  407.         string path = readFilePath();
  408.         fout.open(path);
  409.         for (size_t i = 0; i < list.getSize(); ++i)
  410.             fout << list[i] << " ";
  411.         fout.close();
  412.         cout << "Список успешно сохранён в файл!" << endl;
  413.     }
  414.  
  415.     void selectMenuItem(int menuItem, SinglyLinkedList<int>& list)
  416.     {
  417.         int data = 0;
  418.         size_t index = 0;
  419.         switch (menuItem)
  420.         {
  421.         case 1:
  422.             cout << "Введите элемент списка:" << endl;
  423.             data = readElement(data);
  424.             list.push_back(data);
  425.             break;
  426.         case 2:
  427.             cout << "Введите индекс удаляемого элемента:" << endl;
  428.             index = readDeletableElementIndex(index, list);
  429.             list.removeAt(index);
  430.             break;
  431.         case 3:
  432.             cout << "Введите элемент:\n";
  433.             data = readElement(data);
  434.             cout << "Вхождений элемента " << data << " в список: " << allEntryOfElement(data, list) << endl;
  435.             break;
  436.         case 4:
  437.             saveList(list);
  438.             break;
  439.         case 5:
  440.             exit(0);
  441.             break;
  442.         }
  443.         print(list);
  444.     }
  445.  
  446.     void showMenu(SinglyLinkedList<int> list)
  447.     {
  448.         bool item5 = true;
  449.         cout << "Выберете один из пунктов меню :" << endl;
  450.         cout << "1. Добавить новый элемент." << endl;
  451.         cout << "2. Удалить элемент." << endl;
  452.         cout << "3. Подсчитать количество всех вхождений заданного элемента." << endl;
  453.         cout << "4. Сохранить список в файл." << endl;
  454.         cout << "5. Завершить программу." << endl;
  455.         selectMenuItem(getMainMenuItem(item5), list);
  456.         showMenu(list);
  457.     }
  458.  
  459.     void selectMainMenuItem(int menuItem)
  460.     {
  461.         SinglyLinkedList<int> list;
  462.         switch (menuItem)
  463.         {
  464.         case 1:
  465.             getListFromFile(list);
  466.             break;
  467.         case 2:
  468.             getListElementFromConsole(list);
  469.             break;
  470.         case 3:
  471.             cout << "Введите размер списка\n";
  472.             list.build_empty(readSizeOfEmptyList());
  473.             break;
  474.         }
  475.         print(list);
  476.         showMenu(list);
  477.     }
  478.  
  479.     void showMainMenu()
  480.     {
  481.         bool item5 = false;
  482.         cout << "Выберете один из пунктов меню :" << endl;
  483.         cout << "1. Открыть список из файла." << endl;
  484.         cout << "2. Создать новый список." << endl;
  485.         cout << "3. Создать новый пустой список указанного размера." << endl;
  486.         selectMainMenuItem(getMainMenuItem(item5));
  487.     }
  488. }
  489.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement