Advertisement
MaksNew

Untitled

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