Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Дьяченко Максим Артёмович. ПС-19-1. Вариант 3. Лаб №5.
- //P.S. Индексация в моём списке идёт с единицы.
- #include <fstream>
- #include <cstring>
- #include <iostream>
- using namespace std;
- struct Node { //Узел двунаправленного списка.
- int value; // Данные.
- Node *next, *prev; //Указатели на следующий и предыдущий элементы двунаправленного списка.
- };
- class MyList { //Двунаправленный список.
- // Голова, хвост.
- Node * Head, * Tail;
- // Количество элементов.
- int Count;
- public:
- // Конструктор.
- MyList();
- // Деструктор.
- ~MyList();
- // Получить количество.
- int GetCount();
- // Получить элемент списка.
- Node* GetNode(int);
- // Удалить весь список.
- void DelAll();
- // Удаление элемента, если параметр не указывается,
- // то функция его запрашивает.
- void Del(int pos = 0);
- // Вставка элемента, если параметр не указывается,
- // то функция его запрашивает.
- void Insert(int pos = 0);
- // Добавление в конец списка.
- void AddTail(int n);
- // Добавление в начало списка.
- void AddHead(int n);
- // Печать списка.
- void Print();
- // Печать определенного элемента.
- void Print(int pos);
- };
- MyList::MyList() {
- // Изначально список пуст.
- Head = Tail = NULL;
- Count = 0;
- }
- MyList::~MyList() {
- // Удаляем все элементы.
- DelAll();
- }
- //P.S. Данная функция не была использована в программе, но была в списке обязательных функций.
- void MyList::AddHead(int n) {
- // Новый элемент.
- Node* temp = new Node;
- // Предыдущего нет.
- temp->prev = 0;
- // Заполняем данные.
- temp->value = n;
- // Следующий - бывшая голова.
- temp->next = Head;
- // Если элементы есть?
- if (Head != 0)
- Head->prev = temp;
- // Если элемент первый, то он одновременно и голова и хвост.
- if (Count == 0)
- Head = Tail = temp;
- else
- // Иначе новый элемент - головной.
- Head = temp;
- Count++;
- }
- void MyList::AddTail(int n) {
- // Создаем новый элемент.
- Node* temp = new Node;
- // Следующего нет.
- temp->next = 0;
- // Заполняем данные.
- temp->value = n;
- // Предыдущий - бывший хвост.
- temp->prev = Tail;
- // Если элементы есть?
- if (Tail != 0)
- Tail->next = temp;
- // Если элемент первый, то он одновременно и голова и хвост.
- if (Count == 0)
- Head = Tail = temp;
- else
- // Иначе новый элемент - хвостовой.
- Tail = temp;
- Count++;
- }
- //P.S. Данная функция не была использована в программе, но была в списке обязательных функций.
- void MyList::Insert(int pos) {
- // Если параметр отсутствует или равен 0, то запрашиваем его.
- if (pos == 0) {
- cout << "Input position: ";
- cin >> pos;
- }
- // Позиция от 1 до Count?
- if (pos < 1 || pos > Count + 1) {
- // Неверная позиция.
- cout << "Incorrect position !!!\n";
- return;
- }
- // Если вставка в конец списка.
- if (pos == Count + 1) {
- // Вставляемые данные.
- int data;
- cout << "Input new number: ";
- cin >> data;
- // Добавление в конец списка.
- AddTail(data);
- return;
- }
- else if (pos == 1) {
- // Вставляемые данные.
- int data;
- cout << "Input new number: ";
- cin >> data;
- // Добавление в начало списка.
- AddHead(data);
- return;
- }
- // Счетчик.
- int i = 1;
- // Отсчитываем от головы n - 1 элементов.
- Node* Ins = Head;
- while (i < pos) {
- // Доходим до элемента,
- // перед которым вставляемся.
- Ins = Ins->next;
- i++;
- }
- // Доходим до элемента,
- // который предшествует.
- Node* PrevIns = Ins->prev;
- // Создаем новый элемент.
- Node* temp = new Node;
- // Вводим данные.
- cout << "Input new number: ";
- cin >> temp->value;
- // Настройка связей.
- if (PrevIns != 0 && Count != 1)
- PrevIns->next = temp;
- temp->next = Ins;
- temp->prev = PrevIns;
- Ins->prev = temp;
- Count++;
- }
- void MyList::Del(int pos) {
- // Если параметр отсутствует или равен 0, то запрашиваем его.
- if (pos == 0) {
- cout << "Input position: ";
- cin >> pos;
- }
- // Позиция от 1 до Count?
- if (pos < 1 || pos > Count) {
- // Неверная позиция.
- cout << "Incorrect position !!!\n";
- return;
- }
- // Счетчик.
- int i = 1;
- Node* Del = Head;
- while (i < pos) {
- // Доходим до элемента,
- // который удаляется.
- Del = Del->next;
- i++;
- }
- // Доходим до элемента,
- // который предшествует удаляемому.
- Node* PrevDel = Del->prev;
- // Доходим до элемента, который следует за удаляемым.
- Node* AfterDel = Del->next;
- // Если удаляем не голову.
- if (PrevDel != 0 && Count != 1)
- PrevDel->next = AfterDel;
- // Если удаляем не хвост.
- if (AfterDel != 0 && Count != 1)
- AfterDel->prev = PrevDel;
- // Удаляются крайние?
- if (pos == 1)
- Head = AfterDel;
- if (pos == Count)
- Tail = PrevDel;
- // Удаление элемента.
- delete Del;
- Count--;
- }
- void MyList::Print(int pos) {
- // Позиция от 1 до Count?
- if (pos < 1 || pos > Count) {
- // Неверная позиция.
- cout << "Incorrect position !!!\n";
- return;
- }
- Node* temp;
- // Определяем с какой стороны
- // быстрее двигаться.
- if (pos <= Count / 2) {
- // Отсчет с головы.
- temp = Head;
- int i = 1;
- while (i < pos) {
- // Двигаемся до нужного элемента.
- temp = temp->next;
- i++;
- }
- }
- else {
- // Отсчет с хвоста.
- temp = Tail;
- int i = 1;
- while (i <= Count - pos) {
- // Двигаемся до нужного элемента.
- temp = temp->prev;
- i++;
- }
- }
- // Вывод элемента.
- cout << temp->value << endl;
- }
- void MyList::Print() {
- // Если в списке присутствуют элементы, то пробегаем по нему
- // и печатаем элементы, начиная с головного.
- if (Count != 0) {
- Node* temp = Head;
- cout << "( ";
- while (temp->next != 0) {
- cout << temp->value << ", ";
- temp = temp->next;
- }
- cout << temp->value << " )\n";
- }
- }
- void MyList::DelAll() {
- // Пока остаются элементы, удаляем по одному с головы.
- while (Count != 0)
- Del(1);
- }
- int MyList::GetCount() {
- return Count;
- }
- Node* MyList::GetNode(int pos) {
- Node* temp = Head;
- // Позиция от 1 до Count?
- if (pos < 1 || pos > Count)
- {
- // Неверная позиция.
- cout << "Incorrect position !!!\n";
- return 0;
- }
- int i = 1;
- // Ищем нужный нам элемент.
- while (i < pos && temp != 0)
- {
- temp = temp->next;
- i++;
- }
- if (temp == 0)
- return 0;
- else
- return temp;
- }
- //ГЛАВНАЯ ФУНКЦИЯ.
- int main() {
- setlocale(LC_ALL, "rus");
- ifstream fin("Info.txt");
- ofstream fout("Result.txt");
- MyList trainsList; //Список с номерами поездов и кол-вами свободных мест в вагонах.
- char info[300] = "";
- char* token = nullptr;
- char* nextToken = nullptr;
- char numbers[500];
- int n; //количество поездов
- int trainNumber;
- //Выведем информацию по оформлению нашего списка из Info.txt на экран.
- fin.getline(info, 250); cout << info << endl;
- fin.getline(info, 250); cout << info << endl;
- //Записываем в наш список все номера поездов и кол-во свободных мест для каждого поезда.
- while (!fin.eof()) {
- fin.getline(numbers, 300); //Считали строку с числами.
- token = strtok_s(numbers, " ", &nextToken); //Записали в token первое число(до пробела), а в nextToken - всё, что стоит после пробела.
- while (token != nullptr) { //Пока token равен чему-то...
- trainsList.AddTail(atoi(token)); //Запишем приведённое к типу int значение token в конец списка trainsList.
- token = strtok_s(nullptr, " ", &nextToken); //"Отрезаем" первое число из nextToken и записываем его в token.
- }
- }
- //Выведем список на экран и в файл.
- cout << endl <<"Ваш список: "; trainsList.Print();
- fout << endl << "Ваш список: ( ";
- for (int i = 1; i <= trainsList.GetCount(); i++) {
- fout << (*trainsList.GetNode(i)).value << " ";
- }
- fout << ")";
- //Пока список не пуст, будем искать поезда по номерам, выводить все их данные, после чего удалять их из списка.
- int exist = 0; //Переменная, определяющая, существует ли поезд с заданным номером, или же нет.
- int trainIndex; //Номер позиции данного поезда в нашем списке.
- while (trainsList.GetCount() != 0) {
- cout << endl << "Введите номер поезда, о котором вы хотели бы получить нужную информацию: "; cin >> trainNumber;
- //Ищем поезд с заданным номером.
- for (int i = 1; i <= trainsList.GetCount(); i += 4) {
- if ((*trainsList.GetNode(i)).value == trainNumber) {
- exist = 1;
- trainIndex = i;
- }
- }
- //Такой поезд есть?
- switch (exist) {
- //Нет.
- case 0:
- cout << endl << "Данного поезда нет.\n";
- break;
- //Есть.
- case 1:
- //Выводим на экран и в файл все данные о данном поезде.
- cout << "\nПоезд под номером: №" << trainNumber << endl;
- fout << "\nПоезд под номером: №" << trainNumber << endl;
- cout << "Кол-во свободных мест в купе: ";
- trainsList.Print(trainIndex + 1);
- fout << "Кол-во свободных мест в купе: ";
- fout << (*trainsList.GetNode(trainIndex + 1)).value << endl;
- cout << "Кол-во свободных мест в плацкарте: ";
- trainsList.Print(trainIndex + 2);
- fout << "Кол-во свободных мест в плацкарте: ";
- fout << (*trainsList.GetNode(trainIndex + 2)).value << endl;
- cout << "Кол-во свободных мест в общем вагоне: ";
- trainsList.Print(trainIndex + 3);
- fout << "Кол-во свободных мест в общем вагоне: ";
- fout << (*trainsList.GetNode(trainIndex + 3)).value << endl;
- //Удалим всю информацию о данном поезде.
- for (int i = 1; i <= 4; i++) {
- trainsList.Del(trainIndex);
- }
- //Выведем на экран и в файл список после удаления данного поезда.
- if (trainsList.GetCount() != 0) { //Если поезда ещё остались.
- cout << endl << "Ваш список после очистки: "; trainsList.Print();
- fout << endl << "Ваш список после очистки: ( ";
- for (int i = 1; i <= trainsList.GetCount(); i++) {
- fout << (*trainsList.GetNode(i)).value << " ";
- }
- fout << ")";
- }
- else { //Если список уже пуст.
- cout << endl << "Ваш список пуст.\n\n";
- fout << endl << "Ваш список пуст.\n\n";
- }
- break;
- }
- exist = 0;
- }
- //Закроем потоки ввода/вывода.
- fin.close();
- fout.close();
- system("pause");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment