MrGhost75

LAB10_VAR3

Jun 4th, 2020
712
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.80 KB | None | 0 0
  1. //Дьяченко Максим Артёмович. ПС-19-1. Вариант 3. Лаб №5.
  2. //P.S. Индексация в моём списке идёт с единицы.
  3.  
  4. #include <fstream>
  5. #include <cstring>
  6. #include <iostream>
  7.  
  8. using namespace std;
  9.  
  10. struct Node { //Узел двунаправленного списка.
  11.     int value; // Данные.
  12.     Node *next, *prev; //Указатели на следующий и предыдущий элементы двунаправленного списка.
  13. };
  14.  
  15. class MyList { //Двунаправленный список.
  16.  
  17.     // Голова, хвост.
  18.     Node * Head, * Tail;
  19.     // Количество элементов.
  20.     int Count;
  21.  
  22. public:
  23.  
  24.     // Конструктор.
  25.     MyList();
  26.     // Деструктор.
  27.     ~MyList();
  28.  
  29.     // Получить количество.
  30.     int GetCount();
  31.     // Получить элемент списка.
  32.     Node* GetNode(int);
  33.  
  34.     // Удалить весь список.
  35.     void DelAll();
  36.     // Удаление элемента, если параметр не указывается,
  37.     // то функция его запрашивает.
  38.     void Del(int pos = 0);
  39.     // Вставка элемента, если параметр не указывается,
  40.     // то функция его запрашивает.
  41.     void Insert(int pos = 0);
  42.  
  43.     // Добавление в конец списка.
  44.     void AddTail(int n);
  45.  
  46.     // Добавление в начало списка.
  47.     void AddHead(int n);
  48.  
  49.     // Печать списка.
  50.     void Print();
  51.  
  52.     // Печать определенного элемента.
  53.     void Print(int pos);
  54. };
  55.  
  56. MyList::MyList() {
  57.     // Изначально список пуст.
  58.     Head = Tail = NULL;
  59.     Count = 0;
  60. }
  61.  
  62. MyList::~MyList() {
  63.     // Удаляем все элементы.
  64.     DelAll();
  65. }
  66.  
  67. //P.S. Данная функция не была использована в программе, но была в списке обязательных функций.
  68. void MyList::AddHead(int n) {
  69.     // Новый элемент.
  70.     Node* temp = new Node;
  71.  
  72.     // Предыдущего нет.
  73.     temp->prev = 0;
  74.     // Заполняем данные.
  75.     temp->value = n;
  76.     // Следующий - бывшая голова.
  77.     temp->next = Head;
  78.  
  79.     // Если элементы есть?
  80.     if (Head != 0)
  81.         Head->prev = temp;
  82.  
  83.     // Если элемент первый, то он одновременно и голова и хвост.
  84.     if (Count == 0)
  85.         Head = Tail = temp;
  86.     else
  87.         // Иначе новый элемент - головной.
  88.         Head = temp;
  89.  
  90.     Count++;
  91. }
  92.  
  93. void MyList::AddTail(int n) {
  94.     // Создаем новый элемент.
  95.     Node* temp = new Node;
  96.     // Следующего нет.
  97.     temp->next = 0;
  98.     // Заполняем данные.
  99.     temp->value = n;
  100.     // Предыдущий - бывший хвост.
  101.     temp->prev = Tail;
  102.  
  103.     // Если элементы есть?
  104.     if (Tail != 0)
  105.         Tail->next = temp;
  106.  
  107.     // Если элемент первый, то он одновременно и голова и хвост.
  108.     if (Count == 0)
  109.         Head = Tail = temp;
  110.     else
  111.         // Иначе новый элемент - хвостовой.
  112.         Tail = temp;
  113.  
  114.     Count++;
  115. }
  116.  
  117. //P.S. Данная функция не была использована в программе, но была в списке обязательных функций.
  118. void MyList::Insert(int pos) {
  119.     // Если параметр отсутствует или равен 0, то запрашиваем его.
  120.     if (pos == 0) {
  121.         cout << "Input position: ";
  122.         cin >> pos;
  123.     }
  124.  
  125.     // Позиция от 1 до Count?
  126.     if (pos < 1 || pos > Count + 1) {
  127.         // Неверная позиция.
  128.         cout << "Incorrect position !!!\n";
  129.         return;
  130.     }
  131.  
  132.     // Если вставка в конец списка.
  133.     if (pos == Count + 1) {
  134.         // Вставляемые данные.
  135.         int data;
  136.         cout << "Input new number: ";
  137.         cin >> data;
  138.         // Добавление в конец списка.
  139.         AddTail(data);
  140.         return;
  141.     }
  142.     else if (pos == 1) {
  143.         // Вставляемые данные.
  144.         int data;
  145.         cout << "Input new number: ";
  146.         cin >> data;
  147.         // Добавление в начало списка.
  148.         AddHead(data);
  149.         return;
  150.     }
  151.  
  152.     // Счетчик.
  153.     int i = 1;
  154.  
  155.     // Отсчитываем от головы n - 1 элементов.
  156.     Node* Ins = Head;
  157.  
  158.     while (i < pos) {
  159.         // Доходим до элемента,
  160.         // перед которым вставляемся.
  161.         Ins = Ins->next;
  162.         i++;
  163.     }
  164.  
  165.     // Доходим до элемента,
  166.     // который предшествует.
  167.     Node* PrevIns = Ins->prev;
  168.  
  169.     // Создаем новый элемент.
  170.     Node* temp = new Node;
  171.  
  172.     // Вводим данные.
  173.     cout << "Input new number: ";
  174.     cin >> temp->value;
  175.  
  176.     // Настройка связей.
  177.     if (PrevIns != 0 && Count != 1)
  178.         PrevIns->next = temp;
  179.  
  180.     temp->next = Ins;
  181.     temp->prev = PrevIns;
  182.     Ins->prev = temp;
  183.  
  184.     Count++;
  185. }
  186.  
  187. void MyList::Del(int pos) {
  188.     // Если параметр отсутствует или равен 0, то запрашиваем его.
  189.     if (pos == 0) {
  190.         cout << "Input position: ";
  191.         cin >> pos;
  192.     }
  193.     // Позиция от 1 до Count?
  194.     if (pos < 1 || pos > Count) {
  195.         // Неверная позиция.
  196.         cout << "Incorrect position !!!\n";
  197.         return;
  198.     }
  199.  
  200.     // Счетчик.
  201.     int i = 1;
  202.  
  203.     Node* Del = Head;
  204.  
  205.     while (i < pos) {
  206.         // Доходим до элемента,
  207.         // который удаляется.
  208.         Del = Del->next;
  209.         i++;
  210.     }
  211.  
  212.     // Доходим до элемента,
  213.     // который предшествует удаляемому.
  214.     Node* PrevDel = Del->prev;
  215.     // Доходим до элемента, который следует за удаляемым.
  216.     Node* AfterDel = Del->next;
  217.  
  218.     // Если удаляем не голову.
  219.     if (PrevDel != 0 && Count != 1)
  220.         PrevDel->next = AfterDel;
  221.     // Если удаляем не хвост.
  222.     if (AfterDel != 0 && Count != 1)
  223.         AfterDel->prev = PrevDel;
  224.  
  225.     // Удаляются крайние?
  226.     if (pos == 1)
  227.         Head = AfterDel;
  228.     if (pos == Count)
  229.         Tail = PrevDel;
  230.  
  231.     // Удаление элемента.
  232.     delete Del;
  233.  
  234.     Count--;
  235. }
  236.  
  237. void MyList::Print(int pos) {
  238.     // Позиция от 1 до Count?
  239.     if (pos < 1 || pos > Count) {
  240.         // Неверная позиция.
  241.         cout << "Incorrect position !!!\n";
  242.         return;
  243.     }
  244.  
  245.     Node* temp;
  246.  
  247.     // Определяем с какой стороны
  248.     // быстрее двигаться.
  249.     if (pos <= Count / 2) {
  250.         // Отсчет с головы.
  251.         temp = Head;
  252.         int i = 1;
  253.  
  254.         while (i < pos) {
  255.             // Двигаемся до нужного элемента.
  256.             temp = temp->next;
  257.             i++;
  258.         }
  259.     }
  260.     else {
  261.         // Отсчет с хвоста.
  262.         temp = Tail;
  263.         int i = 1;
  264.  
  265.         while (i <= Count - pos) {
  266.             // Двигаемся до нужного элемента.
  267.             temp = temp->prev;
  268.             i++;
  269.         }
  270.     }
  271.     // Вывод элемента.
  272.     cout << temp->value << endl;
  273. }
  274.  
  275. void MyList::Print() {
  276.     // Если в списке присутствуют элементы, то пробегаем по нему
  277.     // и печатаем элементы, начиная с головного.
  278.     if (Count != 0) {
  279.  
  280.         Node* temp = Head;
  281.  
  282.         cout << "( ";
  283.  
  284.         while (temp->next != 0) {
  285.             cout << temp->value << ", ";
  286.             temp = temp->next;
  287.         }
  288.  
  289.         cout << temp->value << " )\n";
  290.     }
  291. }
  292.  
  293. void MyList::DelAll() {
  294.     // Пока остаются элементы, удаляем по одному с головы.
  295.     while (Count != 0)
  296.         Del(1);
  297. }
  298.  
  299. int MyList::GetCount() {
  300.     return Count;
  301. }
  302.  
  303. Node* MyList::GetNode(int pos) {
  304.  
  305.     Node* temp = Head;
  306.  
  307.     // Позиция от 1 до Count?
  308.     if (pos < 1 || pos > Count)
  309.     {
  310.         // Неверная позиция.
  311.         cout << "Incorrect position !!!\n";
  312.         return 0;
  313.     }
  314.  
  315.     int i = 1;
  316.     // Ищем нужный нам элемент.
  317.     while (i < pos && temp != 0)
  318.     {
  319.         temp = temp->next;
  320.         i++;
  321.     }
  322.  
  323.     if (temp == 0)
  324.         return 0;
  325.     else
  326.         return temp;
  327. }
  328.  
  329.  
  330. //ГЛАВНАЯ ФУНКЦИЯ.
  331. int main() {
  332.  
  333.     setlocale(LC_ALL, "rus");
  334.     ifstream fin("Info.txt");
  335.     ofstream fout("Result.txt");
  336.  
  337.     MyList trainsList; //Список с номерами поездов и кол-вами свободных мест в вагонах.
  338.  
  339.     char info[300] = "";
  340.     char* token = nullptr;
  341.     char* nextToken = nullptr;
  342.     char numbers[500];
  343.     int n; //количество поездов
  344.     int trainNumber;
  345.  
  346.     //Выведем информацию по оформлению нашего списка из Info.txt на экран.
  347.     fin.getline(info, 250); cout << info << endl;
  348.     fin.getline(info, 250); cout << info << endl;
  349.  
  350.  
  351.     //Записываем в наш список все номера поездов и кол-во свободных мест для каждого поезда.
  352.     while (!fin.eof()) {
  353.         fin.getline(numbers, 300); //Считали строку с числами.
  354.         token = strtok_s(numbers, " ", &nextToken); //Записали в token первое число(до пробела), а в nextToken - всё, что стоит после пробела.
  355.  
  356.         while (token != nullptr) { //Пока token равен чему-то...
  357.             trainsList.AddTail(atoi(token)); //Запишем приведённое к типу int значение token в конец списка trainsList.
  358.             token = strtok_s(nullptr, " ", &nextToken); //"Отрезаем" первое число из nextToken и записываем его в token.
  359.         }
  360.     }
  361.  
  362.     //Выведем список на экран и в файл.
  363.     cout << endl <<"Ваш список: "; trainsList.Print();
  364.     fout << endl << "Ваш список: ( ";
  365.     for (int i = 1; i <= trainsList.GetCount(); i++) {
  366.         fout << (*trainsList.GetNode(i)).value << " ";
  367.     }
  368.     fout << ")";
  369.  
  370.     //Пока список не пуст, будем искать поезда по номерам, выводить все их данные, после чего удалять их из списка.
  371.     int exist = 0; //Переменная, определяющая, существует ли поезд с заданным номером, или же нет.
  372.     int trainIndex; //Номер позиции данного поезда в нашем списке.
  373.     while (trainsList.GetCount() != 0) {
  374.  
  375.         cout << endl << "Введите номер поезда, о котором вы хотели бы получить нужную информацию: "; cin >> trainNumber;
  376.  
  377.         //Ищем поезд с заданным номером.
  378.         for (int i = 1; i <= trainsList.GetCount(); i += 4) {
  379.             if ((*trainsList.GetNode(i)).value == trainNumber) {
  380.                 exist = 1;
  381.                 trainIndex = i;
  382.             }
  383.         }
  384.  
  385.         //Такой поезд есть?
  386.         switch (exist) {
  387.  
  388.         //Нет.
  389.         case 0:
  390.             cout << endl << "Данного поезда нет.\n";
  391.             break;
  392.  
  393.         //Есть.
  394.         case 1:
  395.  
  396.             //Выводим на экран и в файл все данные о данном поезде.
  397.             cout << "\nПоезд под номером: №" << trainNumber << endl;
  398.             fout << "\nПоезд под номером: №" << trainNumber << endl;
  399.  
  400.             cout << "Кол-во свободных мест в купе: ";
  401.             trainsList.Print(trainIndex + 1);
  402.             fout << "Кол-во свободных мест в купе: ";
  403.             fout << (*trainsList.GetNode(trainIndex + 1)).value << endl;
  404.  
  405.             cout << "Кол-во свободных мест в плацкарте: ";
  406.             trainsList.Print(trainIndex + 2);
  407.             fout << "Кол-во свободных мест в плацкарте: ";
  408.             fout << (*trainsList.GetNode(trainIndex + 2)).value << endl;
  409.  
  410.             cout << "Кол-во свободных мест в общем вагоне: ";
  411.             trainsList.Print(trainIndex + 3);
  412.             fout << "Кол-во свободных мест в общем вагоне: ";
  413.             fout << (*trainsList.GetNode(trainIndex + 3)).value << endl;
  414.  
  415.             //Удалим всю информацию о данном поезде.
  416.             for (int i = 1; i <= 4; i++) {
  417.                 trainsList.Del(trainIndex);
  418.             }
  419.  
  420.             //Выведем на экран и в файл список после удаления данного поезда.
  421.             if (trainsList.GetCount() != 0) { //Если поезда ещё остались.
  422.                 cout << endl << "Ваш список после очистки: "; trainsList.Print();
  423.                 fout << endl << "Ваш список после очистки: ( ";
  424.                 for (int i = 1; i <= trainsList.GetCount(); i++) {
  425.                     fout << (*trainsList.GetNode(i)).value << " ";
  426.                 }
  427.                 fout << ")";
  428.             }
  429.             else { //Если список уже пуст.
  430.                 cout << endl << "Ваш список пуст.\n\n";
  431.                 fout << endl << "Ваш список пуст.\n\n";
  432.             }
  433.  
  434.             break;
  435.         }
  436.  
  437.         exist = 0;
  438.     }
  439.  
  440.     //Закроем потоки ввода/вывода.
  441.     fin.close();
  442.     fout.close();
  443.     system("pause");
  444.     return 0;
  445. }
Advertisement
Add Comment
Please, Sign In to add comment