Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

4 семестр / sr29

.cpp
Скачиваний:
0
Добавлен:
16.11.2025
Размер:
16.12 Кб
Скачать
#include <iostream>
#include <cstring>
#include "myheader.h"
using namespace std;
// 01.05 - добавлен интерфейс, ещё будут добавлены действия с геом. фигурами.
template <class T>
struct Elem { // элемент очереди - по аналогии с элементов стека из примера
    T data;
    Elem* next;
    Elem(const T& data) : data(data), next(0) {}
};

template <class T> // сам шаблон очереди (FIFO)
class Queue {
protected:
    Elem<T>* head; // вершина очереди
    Elem<T>* tail; // последний элемент очереди
    size_t size; // размер
public:
    Queue() : head(0), tail(0), size(0) {} // конструктор по умолчанию
    ~Queue() { // деструктор (пробежка по всем элементам очереди)
        while (head) {
            Elem<T>* temp = head;
            head = head->next;
            delete temp;
        }
    }
    Queue<T>& operator<<(const T& value) { // добавление элемента, операция перегружена
        Elem<T>* newNode = new Elem<T>(value);
        if (!tail) {
            head = tail = newNode;
        } else {
            tail->next = newNode;
            tail = newNode;
        }
        size++;
        return *this;
    }
    bool pop(T& value) { // удаление элемента, само его значение извлекается в value (аргумент), причём если удаление не удалось - даёт ноль
        if (!head) return false;
        value = head->data;
        Elem<T>* temp = head;
        head = head->next;
        delete temp;
        size--;
        if (!head) tail = 0;
        return true;
    }
    void show(){ // показать всю очередь
        Elem<T>* temp = head;
        for(int i=0; i<size; i++){
            cout << temp->data << " ";
            temp = temp->next;
        }
        cout << endl;
        delete temp;
    }
    size_t getSize() const { return size; } // размер
    bool isEmpty() const { return size == 0; } // проверка на то, пуста ли очередь
};
template <> // специализация для int: по сути, то же самое, но добавляем метод для подсчёта суммы
class Queue<int> {
protected:
    Elem<int>* head;
    Elem<int>* tail;
    size_t size;
public:
    Queue() : head(0), tail(0), size(0) {}

    ~Queue() {
        while (head) {
            Elem<int>* temp = head;
            head = head->next;
            delete temp;
        }
    }
    Queue<int>& operator<<(const int& value) {
        Elem<int>* newNode = new Elem<int>(value);
        if (!tail) {
            head = tail = newNode;
        } else {
            tail->next = newNode;
            tail = newNode;
        }
        size++;
        return *this;
    }
    bool pop(int& value) {
        if (!head) return false;
        value = head->data;
        Elem<int>* temp = head;
        head = head->next;
        delete temp;
        size--;
        if (!head) tail = 0;
        return true;
    }
    size_t getSize() const { return size; }
    bool isEmpty() const { return size == 0; }
    int sum() const {
        int total = 0;
        Elem<int>* current = head;
        while (current) {
            total += current->data;
            current = current->next;
        }
        return total;
    }
    void show(){
        Elem<int>* temp = head;
        for(int i=0; i<size; i++){
            cout << temp->data << " ";
            temp = temp->next;
        }
        cout << endl;
        delete temp;
    }
};
template <> // специализация для char: уже через массивы
class Queue<char> {
    char* data; // массив символов
    size_t capacity; // его макс. размер
    size_t head; // индекс вершины
    size_t tail; // индекс последнего элемента
    size_t currentSize; // текущая длина

public:
    Queue(size_t size) : capacity(size), head(0), tail(0), currentSize(0) {
        data = new char[capacity]; // создание символьного массива в конструкторе
    }

    ~Queue() {
        delete[] data;
    }

    Queue<char>& operator<<(const char& value) {
        if (currentSize == capacity) {
            cout << "Превышен размер!" << endl;
        }
        else{
        data[tail] = value;
        tail = (tail + 1);
        currentSize++;
        }
        return *this;
    }

    bool pop(char& value) {
        if (currentSize == 0) return false;
        value = data[head];
        head = (head + 1);
        currentSize--;
        return true;
    }
    void show(){
        for(int i=head; i<tail; i++){
            cout << data[i] << " ";
        }
        cout << endl;
    }

    size_t getSize() const { return currentSize; }
    bool isEmpty() const { return currentSize == 0; }
    size_t getCapacity() const { return capacity; }
};

template <> // специализация, но уже для строк (const char*)
class Queue<const char*> {
private:
    Elem<const char*>* head;
    Elem<const char*>* tail;
    size_t size;

public:
    Queue() : head(0), tail(0), size(0) {}
    ~Queue() {
        while (head) {
            Elem<const char*>* temp = head;
            head = head->next;
            delete[] temp->data;
            delete temp;
        }
    }
    Queue<const char*>& operator<<(const char* value) {
        char* copy = new char[strlen(value) + 1];
        strcpy(copy, value);
        Elem<const char*>* newNode = new Elem<const char*>(copy);
        if (!tail) {
            head = tail = newNode;
        } else {
            tail->next = newNode;
            tail = newNode;
        }
        size++;
        return *this;
    }
    bool pop(const char*& value) {
        if (!head) return false;

        value = head->data;
        Elem<const char*>* temp = head;
        head = head->next;
        delete temp;
        size--;
        if (!head) tail = 0;
        return true;
    }
    void show(){
        Elem<const char *>* temp = head;
        for(int i=0; i<size; i++){
            cout << temp->data << " ";
            temp = temp->next;
        }
        cout << endl;
        delete temp;
    }
    size_t getSize() const { return size; }
    bool isEmpty() const { return size == 0; }
};

template <> // для геометрических фигур
class Queue<GeomFigure*> {
private:
    Elem<GeomFigure*>* head;
    Elem<GeomFigure*>* tail;
    size_t size;

public:
    Queue() : head(0), tail(0), size(0) {}

    ~Queue() {
        while (head) {
            Elem<GeomFigure*>* temp = head;
            head = head->next;
            delete temp;
        }
    }
    Queue<GeomFigure*>& operator<<(GeomFigure* value) {
        Elem<GeomFigure*>* newNode = new Elem<GeomFigure*>(value);
        if (!tail) {
            head = tail = newNode;
        } else {
            tail->next = newNode;
            tail = newNode;
        }
        size++;
        return *this;
    }

    bool pop(GeomFigure*& value) {
        if (!head) return false;
        value = head->data;
        Elem<GeomFigure*>* temp = head;
        head = head->next;
        delete temp;
        size--;
        if (!head) tail = 0;
        return true;
    }
    void show(){
        initwindow(1250,750);
        cout << "Graphic window ON." << endl;
        Elem<GeomFigure*>* temp = head;
        for(int i=0; i<size; i++){
            (temp->data)->Show();
            temp = temp->next;
        }
        delete temp;
        getch(); // Wait for key press.
        closegraph(); // Close graphics.
        cout << "Graphic window OFF." << endl;
    }
    size_t getSize() const { return size; }
    bool isEmpty() const { return size == 0; }
};

int main() {
    int choice, choice_type, choice_type1, sizeq, sizep, tempColor;
    double tempX, tempY, temp1, temp2, temp3, temp4;
    setlocale(LC_ALL, "Rus");
    Queue<int> qINT;
    int tempINT;
    Queue<float> qFLOAT;
    float tempFLOAT;
    Queue<char> *qCHAR;
    char tempCHAR;
    Queue<const char*> qSTRING;
    const char* tempSTRING;
    char* tempST = new char[1];
    Queue<GeomFigure *> qGEOM;
    GeomFigure *tempGEOM;
    /*
    cout << "Очередь из геометрических фигур - окружности и квадрата" << endl;
    Queue<GeomFigure*> figQueue;
    Circle c(1, 2, 5, 6);
    Square s(8, 8, 2, 4);
    figQueue << &c << &s;
    cout << "Удаление элементов и вывод удалённых в данную переменную (geom):" << endl;
    GeomFigure* geom;
    while (figQueue.pop(geom)) {
        geom->Show();
    }
    cout << endl;
    */
    system("cls");
	cout << "\nВыберите действие, которое хотите совершить:"
		<< "\n1 - Создать очередь"
		<< "\n2 - Удалить элементы из очереди"
		<< "\n3 - Показать очередь"
		<< "\n(Ctrl + z Enter – Выход из программы\n";
	cin >> choice;

	while (!feof(stdin))// Начало цикла. Цикл выполняется до тех пор,
						// пока не будет введен символ Ctrl + z.
	{
		{
			switch (choice)
			{
			case 1:
			    cout << "Построение своего списка. Выберите тип: " << endl; // Построение своей очереди
                cout << "1 - целые числа    2 - вещественные числа    3 - символы     4 - строки    5 - геом. фигуры" << endl;
                cin >> choice_type;
                cout << "Введите кол-во элементов, которые хотите ввести:" << endl;
                cin >> sizeq;
                switch(choice_type){
                    case 1:
                    {
                        for(int i=0; i<sizeq; i++){
                            cin >> tempINT;
                            qINT << tempINT;
                        }
                    break;
                    }
                    case 2:
                    {
                        for(int i=0; i<sizeq; i++){
                            cin >> tempFLOAT;
                            qFLOAT << tempFLOAT;
                        }
                    break;
                    }
                    case 3:
                    {
                    Queue<char> q(sizeq);
                    qCHAR=&q;
                    for(int i=0; i<sizeq; i++){
                        cin >> tempCHAR;
                        q << tempCHAR;
                    }
                    break;
                    }
                    case 4:
                    {
                    getchar();
                    Queue<const char*> q;
                    char buffer[32];
                    for(int i=0; i<sizeq; i++){
                        cin.getline(buffer, 32);
                        char* tempST = new char[strlen(buffer) + 1];
                        strcpy(tempST, buffer);
                        qSTRING << tempST;
                    }
                    break;
                    }
                    case 5:
                    {
                    for(int i=0; i<sizeq; i++){
                    cout << "Добавление своей фигуры. Выберите тип: " << endl;
                    cout << "1 - окружность    2 - ромб    3 - треугольник" << endl;
                    cin >> choice_type1;
                    cout << "Введите цвет фигуры (1 - синий, 2 - зелёный, 4 - красный и пр.):" << endl;
                    cin >> tempColor;
                    cout << "Введите координаты центра/начала фигуры:" << endl;
                    cin >> tempX >> tempY;
                    switch(choice_type1){
                        case 1:
                        {
                            cout << "Введите радиус окружности:" << endl;
                            cin >> temp1;
                            Circle *p = new Circle(tempX, tempY, temp1, tempColor);
                            //tempGEOM = p;
                            qGEOM<<p;
                        break;
                        }
                        case 2:
                        {
                            cout << "Введите длину одной диагонали:" << endl;
                            cin >> temp1;
                            cout << "Введите длину другой диагонали:" << endl;
                            cin >> temp2;
                            Romb *p = new Romb(tempX, tempY, tempColor, temp1, temp2);
                            //tempGEOM = p;
                            qGEOM<<p;
                        break;
                        }
                        case 3:
                        {
                        cout << "Введите координаты второй точки:" << endl;
                        cin >> temp1 >> temp2;
                        cout << "Введите координаты третьей точки:" << endl;
                        cin >> temp3 >> temp4;
                        Triangle *p = new Triangle(tempX, tempY, temp1, temp2, temp3, temp4, tempColor);
                        //tempGEOM = p;
                        qGEOM<<p;
                        break;
                        }
                    }
                    }
				break;
                }
            }
            break;
			case 2:
			    cout << "Введите кол-во элементов, которые хотите удалить:" << endl;
                cin >> sizep;
                if (sizep>sizeq) sizep=sizeq;
				switch(choice_type){
                    case 1:
                    {
                        for(int i=0; i<sizep; i++){
                            qINT.pop(tempINT);
                            cout << "Удалено: " << tempINT << endl;
                        }
                        break;
                    }
                    case 2:
                    {
                        for(int i=0; i<sizep; i++){
                            qFLOAT.pop(tempFLOAT);
                            cout << "Удалено: " << tempFLOAT << endl;
                        }
                        break;
                    }
                    case 3:
                    {
                        for(int i=0; i<sizep; i++){
                            qCHAR->pop(tempCHAR);
                            cout << "Удалено: " << tempCHAR << endl;
                        }
                    break;
                    }
                    case 4:
                    {
                        for(int i=0; i<sizep; i++){
                            qSTRING.pop(tempSTRING);
                            cout << "Удалено: " << tempSTRING << endl;
                        }
                    break;
                    }
                    case 5:
                    {
                        for(int i=0; i<sizep; i++){
                            qGEOM.pop(tempGEOM);
                        }
                    break;
                    }
                    default:
                    {
                        cout << "\nОчередь не создана.";
                    break;
                    }
                break;
                }
            case 3:
                {
                switch(choice_type){
                    case 1:
                    {
                        qINT.show();
                    }
                    case 2:
                    {
                        qFLOAT.show();
                    }
                    case 3:
                    {
                        qCHAR->show();
                    break;
                    }
                    case 4:
                    {
                        qSTRING.show();
                    break;
                    }
                    case 5:
                    {
                        qGEOM.show();
                    break;
                    }
                    default:
                    {
                        cout << "\nОчередь не создана.";
                    break;
                    }
                }
				break;
			}
			default:
				cout << "\nКоманда меню с номером" << choice
					<< "отсутствует\n";
				break;
			}
		}

		cout << "\nВыберите действие, которое хотите совершить:"
            << "\n1 - Создать очередь"
            << "\n2 - Удалить элементы из очереди"
            << "\n3 - Показать очередь"
            << "\n(Ctrl + z Enter – Выход из программы\n";
        cin >> choice;
	}
	system("pause");
    return 0;
};
Соседние файлы в папке 4 семестр