Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <regex>
- #include <sstream>
- #include <filesystem>
- #include <fstream>
- using namespace std;
- template<typename T>
- class SinglyLinkedList
- {
- public:
- SinglyLinkedList();
- SinglyLinkedList(const SinglyLinkedList& other);
- ~SinglyLinkedList();
- void push_back(T data);
- void push_front(T data);
- void pop_front();
- void clear();
- void build_empty(size_t sizeOfList);
- void insert(T data, int index);
- void removeAt(int index);
- void pop_back();
- int getSize(){ return size;}
- T operator[] (const int index);
- private:
- template<typename T>
- class Node
- {
- public:
- Node *pNext;
- T data;
- Node(T data = T(), Node *pNext = nullptr)
- {
- this->data = data;
- this->pNext = pNext;
- }
- };
- Node<T> *head;
- size_t size;
- };
- template<typename T>
- SinglyLinkedList<T>::SinglyLinkedList()
- {
- size = 0;
- head = nullptr;
- }
- template<typename T>
- SinglyLinkedList<T>::SinglyLinkedList(const SinglyLinkedList& other) : SinglyLinkedList()
- {
- Node<T> *current = other.head;
- while (current != nullptr)
- {
- push_back(current->data);
- current = current->pNext;
- }
- }
- //template<typename T>
- //SinglyLinkedList<T>::SinglyLinkedList(const SinglyLinkedList& other) : SinglyLinkedList() {
- // for (auto current = other.head; current != nullptr; current = current->pNext) {
- // push_back(current->data);
- // }
- //}
- template<typename T>
- SinglyLinkedList<T>::~SinglyLinkedList()
- {
- clear();
- }
- template<typename T>
- void SinglyLinkedList<T>::push_back(T data)
- {
- if (head == nullptr)
- {
- head = new Node<T>(data);
- }
- else
- {
- Node<T> *current = this->head;
- while (current->pNext != nullptr)
- {
- current = current->pNext;
- }
- current->pNext = new Node<T>(data);
- }
- size++;
- }
- template<typename T>
- void SinglyLinkedList<T>::pop_front()
- {
- Node<T> *temp = head;
- head = head->pNext;
- delete temp;
- size--;
- }
- template<typename T>
- T SinglyLinkedList<T>::operator[](const int index)
- {
- size_t counter = 0;
- Node<T> *current = this->head;
- while (current != nullptr)
- {
- if (counter == index)
- {
- return current->data;
- }
- ++counter;
- current = current->pNext;
- }
- }
- template<typename T>
- void SinglyLinkedList<T>::clear()
- {
- while (size)
- {
- pop_front();
- }
- }
- template<typename T>
- void SinglyLinkedList<T>::build_empty(size_t sizeOfList)
- {
- for (size_t i = 0; i < sizeOfList; ++i)
- {
- push_back(T());
- }
- }
- template<typename T>
- void SinglyLinkedList<T>::push_front(T data)
- {
- head = new Node<T>(data, head);
- size++;
- }
- template<typename T>
- void SinglyLinkedList<T>::insert(T data, int index)
- {
- if (index == 0)
- {
- push_front(data);
- }
- else
- {
- Node<T>* previous = this->head;
- for (size_t i = 0; i < index - 1; ++i)
- {
- previous = previous->pNext;
- }
- Node<T> *newNode = new Node<T>(data, previous->pNext);
- previous->pNext = newNode;
- ++size;
- }
- }
- template<typename T>
- void SinglyLinkedList<T>::removeAt(int index)
- {
- if (index == 0)
- {
- pop_front();
- }
- else
- {
- Node<T> *previous = this->head;
- for (size_t i = 0; i < index - 1; ++i)
- {
- previous = previous->pNext;
- }
- Node<T> *temp = previous->pNext;
- previous->pNext = temp->pNext;
- delete temp;
- size--;
- }
- }
- template<typename T>
- void SinglyLinkedList<T>::pop_back()
- {
- removeAt(size - 1);
- }
- template<typename T>
- void print(SinglyLinkedList<T> list)
- {
- cout << endl << "№\t" << "элемент" << endl;
- for (size_t i = 0; i < list.getSize(); ++i)
- {
- cout << i + 1 << "\t" << list[i] << endl;
- }
- cout << endl;
- //showMenu(getMainMenuItem());
- }
- template<typename T>
- unsigned short allEntryOfElement(T element, SinglyLinkedList<T> list)
- {
- unsigned short counter = 0;
- for (size_t i = 0; i < list.getSize(); ++i)
- {
- if (element == list[i])
- counter++;
- }
- return counter;
- }
- bool isFileCorrect(string path)
- {
- string inputline;
- regex regular("^(\\d+\\s*)+$");
- fstream fin(path, ios_base::in);
- bool isCorrect = true;
- while (!fin.eof() && isCorrect)
- {
- getline(fin, inputline);
- if (!(regex_match(inputline.c_str(), regular)))
- isCorrect = false;
- }
- fin.close();
- return isCorrect;
- }
- string readFilePath(bool flag)
- {
- string path;
- bool isIncorrect;
- do
- {
- isIncorrect = false;
- cout << "Введите абсолютный путь к файлу: " << endl;
- cin >> path;
- if (!filesystem::exists(path))
- {
- cout << "Файл не найден. Проверьте введённый путь." << endl;
- isIncorrect = true;
- }
- else
- {
- if (flag && !isFileCorrect(path))
- {
- cout << "Ошибка при чтении файла! Проверьте данные и попробуйте ещё раз!" << endl;
- isIncorrect = true;
- }
- }
- } while (isIncorrect);
- return path;
- }
- template<typename T>
- void getListFromFile(SinglyLinkedList<T> &list)
- {
- bool flag = true;
- string path = readFilePath(flag);
- string inputline;
- cmatch res;
- regex reg("(\\d+)\\s*");
- fstream fin(path, std::ios_base::in);
- while (!fin.eof())
- {
- getline(fin, inputline);
- auto inputline_begin = sregex_iterator(inputline.begin(), inputline.end(), reg);
- auto inputline_end = sregex_iterator();
- for (auto i = inputline_begin; i != inputline_end; ++i)
- {
- list.push_back(stoi((*i).str()));
- }
- }
- fin.close();
- }
- int readElement(int data)
- {
- string inputLine;
- bool isIncorrect;
- do
- {
- isIncorrect = false;
- try
- {
- cin >> inputLine;
- data = stoi(inputLine);
- }
- catch (...)
- {
- isIncorrect = true;
- cout << "Введите целое число!" << endl;
- }
- } while (isIncorrect);
- return data;
- }
- void getListElementFromConsole(SinglyLinkedList<int> &list)
- {
- int data = 0;
- cout << "Введите элемент списка: \n";
- data = readElement(data);
- list.push_back(data);
- }
- int getMainMenuItem(bool item5)
- {
- bool isIncorrect;
- string inputLine;
- int item = 0;
- do
- {
- isIncorrect = false;
- try
- {
- cin >> inputLine;
- item = stoi(inputLine);
- }
- catch (...)
- {
- isIncorrect = true;
- cout << "Введите целое число!" << endl;
- }
- if (!item5 && (item != 1) && (item != 2) && (item != 3) && !isIncorrect)
- {
- cout << "Выберете один из пунктов меню!\n";
- isIncorrect = true;
- }
- if (item5 && (item != 1) && (item != 2) && (item != 3) && (item != 4) && (item != 5) && !isIncorrect)
- {
- cout << "Выберете один из пунктов меню!\n";
- isIncorrect = true;
- }
- } while (isIncorrect);
- return item;
- }
- int readSizeOfEmptyList()
- {
- bool isIncorrect;
- string inputLine;
- int size;
- do
- {
- isIncorrect = false;
- try
- {
- cin >> inputLine;
- size = stoi(inputLine);
- }
- catch (...)
- {
- isIncorrect = true;
- cout << "Введите целое число!" << endl;
- }
- if (!isIncorrect && size < 1 && size > 2000000)
- {
- cout << "Введите положительное число до 2*10^6!\n";
- isIncorrect = true;
- }
- } while (isIncorrect);
- return size;
- }
- size_t readDeletableElementIndex(size_t index, SinglyLinkedList<int> &list)
- {
- bool isIncorrect;
- string inputLine;
- do
- {
- isIncorrect = false;
- try
- {
- cin >> inputLine;
- index = stoi(inputLine);
- }
- catch (...)
- {
- isIncorrect = true;
- cout << "Введите целое число!" << endl;
- }
- if (!isIncorrect && index+1 < list.getSize() && index+1 > list.getSize())
- {
- cout << "Введите индекс в преедлах размера списка!\n";
- isIncorrect = true;
- }
- } while (isIncorrect);
- return index-1;
- }
- string readFilePath()
- {
- string path;
- bool isIncorrect;
- isIncorrect = true;
- do
- {
- cout << "Введите абсолютный путь к файлу: " << endl;
- cin >> path;
- if (!std::filesystem::exists(path))
- cout << "Файл не найден. Проверьте введённый путь." << endl;
- else
- isIncorrect = false;
- } while (isIncorrect);
- return path;
- }
- void saveList(SinglyLinkedList<int>& list)
- {
- ofstream fout;
- string path = readFilePath();
- fout.open(path);
- for (size_t i = 0; i < list.getSize(); ++i)
- fout << list[i] << " ";
- fout.close();
- cout << "Список успешно сохранён в файл!" << endl;
- }
- void selectMenuItem(int menuItem, SinglyLinkedList<int> &list)
- {
- int data = 0;
- size_t index = 0;
- switch (menuItem)
- {
- case 1:
- cout << "Введите элемент списка:" << endl;
- data = readElement(data);
- list.push_back(data);
- break;
- case 2:
- cout << "Введите индекс удаляемого элемента:" << endl;
- index = readDeletableElementIndex(index, list);
- list.removeAt(index);
- break;
- case 3:
- cout << "Введите элемент:\n";
- data = readElement(data);
- cout << "Вхождений элемента " << data << " в список: " << allEntryOfElement(data, list) << endl;
- break;
- case 4:
- saveList(list);
- break;
- case 5:
- exit(0);
- break;
- }
- print(list);
- }
- void showMenu(SinglyLinkedList<int> list)
- {
- bool item5 = true;
- cout << "Выберете один из пунктов меню :" << endl;
- cout << "1. Добавить новый элемент." << endl;
- cout << "2. Удалить элемент." << endl;
- cout << "3. Подсчитать количество всех вхождений заданного элемента." << endl;
- cout << "4. Сохранить список в файл." << endl;
- cout << "5. Завершить программу." << endl;
- selectMenuItem(getMainMenuItem(item5), list);
- showMenu(list);
- }
- void selectMainMenuItem(int menuItem)
- {
- SinglyLinkedList<int> list;
- switch (menuItem)
- {
- case 1:
- getListFromFile(list);
- break;
- case 2:
- getListElementFromConsole(list);
- break;
- case 3:
- cout << "Введите размер списка\n";
- list.build_empty(readSizeOfEmptyList());
- break;
- }
- print(list);
- showMenu(list);
- }
- void showMainMenu()
- {
- bool item5 = false;
- cout << "Выберете один из пунктов меню :" << endl;
- cout << "1. Открыть список из файла." << endl;
- cout << "2. Создать новый список." << endl;
- cout << "3. Создать новый пустой список указанного размера." << endl;
- selectMainMenuItem(getMainMenuItem(item5));
- }
- int main()
- {
- setlocale(LC_ALL, "ru");
- showMainMenu();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement