Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "pch.h"
- #include <iostream>
- using namespace std;
- /*------------------------------------------------------------------- СТЭК ---------------------------------------------------------------*/
- /*
- Тип данных для стэка целых чисел Stack (последний пришёл - первый ушёл)
- @data - значение целого числа в элементе стэка
- @next - указатель на следующий элемент стэка (nullptr, если это элемент из основания стэка)
- */
- struct Stack
- {
- int data; // поле данных
- struct Stack* next; // указатель на следующий элемент cтэка
- };
- /*
- Операции над стэком Stack -----------------------
- В линейном списке мы использовали для доступа к оригинальному списку двойной указатель LinearList**, т.е. указатель на указатель на наш тип данных - вроде как (LinearList*)*,
- это было необходимо для того, чтобы в наших функциях можно было менять исходный список.
- Здесь используем альтернативный подход: будем прямо в функции явно ждать адрес передаваемого указателя (Stack* &top)
- Теперь чтобы менять исходные данные, нам можно передавать их в функцию как обычную переменную, что упрощает читабельность кода.
- */
- // добавление элемента значения @data = value в конец стэка
- void pushStack(Stack* &top, const int value)
- {
- Stack* e = new Stack; // объявляем новую динамическую переменную типа Stack и выделяем под неё память
- e->data = value; // записываем в неё значение value, которое помещается в стэк
- e->next = top; // связываем новый элемент стэка с предыдущим
- top = e; // новый элемент стека становится его вершиной
- }
- // извлечение значения из стэка с удалением верхнего элемента
- int popStack(Stack* &top)
- {
- int tmp = top->data; // извлекаем в переменную tmp значение в вершине стэка
- Stack *e = top; // запоминаем указатель на вершину стэка, чтобы затем освободить выделенную под элемент e память
- top = top->next; // вершиной становится предшествующий top элемент
- delete e; // освобождаем память (удаляем извлеченную вершину стэка)
- return tmp; // возвращаем значение, которое было в вершине стэка
- }
- // Создание стэка top и инициализация его значениями на основе массива values длины length
- void createStack(Stack* &top, int* values, const int length)
- {
- if (length > 0) // есть смысл инициализировать стэк толькое если передаваемая длина массива length ненулевая
- {
- for (int i = 0; i < length; i++) // в цикле по массиву values...
- {
- pushStack(top, values[i]); // Просто. Пушим. Их. В стэк.
- }
- }
- }
- // Последовательный вывод содержимого стэка top (здесь нам не надо менять исходные данные, поэтому можно обойтись простым указателем на верхний элемент стэка Stack*)
- void printStack(Stack* top)
- {
- cout << endl << "Стэк:" << endl;
- Stack* e = top; // временная переменная e для обхода стэка с вершины до основания без извлечения (удаления) элементов
- while (e != nullptr) // пока не достигнуто основание стэка, т.е. пока временная переменная e не приняла значение равное пустому указателю nullptr
- {
- cout << "[" << e->data << "] -> "; // выводим данные из узла стэка @data
- e = e->next; // сдвигаемся к основанию стэка
- }
- cout << "NULL" << endl; // основание стэка у нас всегда указывает на nullptr (NULL)
- }
- // Очищаем стэк от элементов
- void clearStack(Stack* &top)
- {
- while (top != nullptr) // пока стэк не опустеет
- {
- cout << top << " [" << top->data << "]" << endl;
- popStack(top); // "выкидываем" элементы из стэка
- }
- }
- //-------------------------------------------------------------------------------//
- // Задача 2 лабораторной (по варианту 1)
- //-------------------------------------------------------------------------------//
- void operateStack(Stack* &top)
- {
- cout << endl;
- cout << "------------------------------------------------------" << endl;
- cout << " Определение произведения нечётных значений элементов стека: " << endl;
- cout << "------------------------------------------------------" << endl;
- int mul = 1; // произведение найденных элементов нечетных значений
- int num = 0; // количество найденных элементов (просто для статистики и красоты вывода)
- if (top == nullptr)
- {
- cout << "Стэк пуст...";
- return;
- }
- cout << "Нечетные значения:" << endl;
- while (top != nullptr) // пока не дошли до основания стэка
- {
- int pop = popStack(top); // извлеваем верхнее значение...
- if (pop % 2 != 0) // проверяем нечетность значения, извлеченного из стэка
- {
- cout << pop << endl;
- mul *= pop; // если значение нечетное, перемножаем его с mul
- num++; // ...и подсчитываем количество найденных элементов, удовлетворяющих условиям задачи
- }
- }
- if (num > 0) // если в результате обхода списка что-то нашлось, значит можно выводить произведение
- {
- cout << "Произведение нечетных значений = " << mul << endl;
- }
- else // иначе считать особо нечего, не делить же 0 на 0...
- {
- cout << "Чисел удовлетворяющим условиям задачи в стэке не найдено" << endl;
- }
- }
- int main()
- {
- setlocale(LC_ALL, "Russian");
- const int default_length = 5; // длина инициализационного массива
- int default_data[default_length] = { 1, 4, 3, 44, 7 }; // инициализационный массив значений для инициализации структур
- Stack* stack = nullptr; // переменная для хранения указателя на вершину стэка
- cout << "------------------------------------------------------" << endl;
- cout << " Создание стэка из массива [1,4,3,44,7]: " << endl;
- cout << "------------------------------------------------------" << endl;
- createStack(stack, default_data, default_length);
- printStack(stack);
- cout << endl;
- cout << "------------------------------------------------------" << endl;
- cout << " Добавление элемента в стэк: " << endl;
- cout << "------------------------------------------------------" << endl;
- int StackData = 0;
- cout << "Введите целое число: ";
- cin >> StackData; // записываем введенное число в переменную
- pushStack(stack, StackData);
- printStack(stack);
- cout << endl;
- cout << "------------------------------------------------------" << endl;
- cout << " Извлечение элемента из стэка: " << endl;
- cout << "------------------------------------------------------" << endl;
- popStack(stack);
- printStack(stack);
- // задание лабораторной по варианту 1
- operateStack(stack);
- cout << endl;
- cout << "------------------------------------------------------" << endl;
- cout << " УДАЛЕНИЕ всего стэка: " << endl;
- cout << "------------------------------------------------------" << endl;
- clearStack(stack);
- printStack(stack);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement