Advertisement
MaksNew

SLList.cpp

Feb 28th, 2021
320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 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