Добавил:
okley
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:4 семестр / sr29
.cpp#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;
};
