C++

Класс множество: трехмерный массив

Написать класс Множество – наследник класса Матрица (множество понимается в привычном cмысле – неупорядоченный набор уникальных элементов известной мощности).

В классе реализовать следующие методы:

конструкторы (по умолчанию, с параметрами, копирования);
деструктор;
ввод с клавиатуры, вывод на экран (в виде методов класса и при помощи перегруженных операций потокового ввода и вывода).
Перегрузить следующие операции:

+, += (добавление элемента в множество);
+, += (объединение двух множеств);
– (удаление элемента);
– (разность множеств);
= (присвоение);
== (сравнение по элементам).
Операции: +, += (добавление элемента в множество) реализовать как виртуальные функции.


По сути — это класс, описывающий трехмерные массивы или множества. Объект данного класса — множество, которое содержит size матриц. В классе перегружены различные операции для сложения добавления элементов множества и многое другое.

Посмотрите заголовочный файл many.h класса Many. В интерфейсном файле класса можно увидеть, что объявлены две дружественные функции класса, строки 8 — 9. По сути это даже не функции, это перегруженные операции ввода/вывода. Это значит, что объекты класса можно выводить на экран, привычным для нас способом — строка 20 в Файле с функцией main(). Тоже самое относится и к операции ввода — строка 25. В классе есть три конструктора:

конструктор по умолчанию;
конструктор с параметрами (для создания объекта передаются параметры);
конструктор копии (нужен для создания нового объекта, аналогичного копируемому).
Кроме конструктора, есть деструктор и много методов, работа которых описана в коде.
#ifndef MANY_H
#define MANY_H
 
#include "matrix.h"
 
class Many : /*virtual*/ public Matrix
{
    friend ostream &operator<< (ostream &, const Many &); // перегруженный оператор вывода
    friend istream &operator>> (istream &, Many &); // перегруженный оператор ввода
private:
    Matrix *ptr; // указатель на массив объектов Matrix
    int size; // количество элементов множества
public:
    Many(); // конструктор по умолчанию
    Many(int, int, int); // конструктор с параметрами
    Many(Many &); // конструктор копии
    ~Many(); // десструктор класса Many
 
    Matrix &operator[] (int ); // перегруженная операция взятия индекса
    int getSizeMany() const; // возвратить количество объектов типа Matrix
    int getSizeRow() const
    {
        return ptr->getSizeMat();
    }
 
    int getSizeCol() const
    {
        return ptr->getPtr()->getSize();
    }
 
    void getMany(); // вывод множества
    void setMany(); // заполнение множества
    const Many &operator= (const Many &); // оператор присваивания
    bool operator== (const Many &right) const;// оператор сравнения
    Many &operator- (/*const int & */); // оператор удаления элемента множества по номеру
    Many operator- (const Many &right);
    Many operator+ (const Many &right); // объединение двух множеств
    Many operator+= (const Many &right); // объединение двух множеств
    virtual Many operator+ (const Matrix &right); // добавление элемента в множество
    virtual Many &operator+= (const Matrix &right); // добавление элемента в множество
};
 
#endif // MANY_H

Исполняемый файл many.cpp класса Many.
#include "many.h"
 
#include <iostream>
using std::cout; // пространство имен std для cout
using std::cin; // пространство имен std для cin
 
#include <iomanip> // для манипулятора setw
using std::setw;   // пространство имен std для setw
 
#include <cstdlib>
 
Many::Many() // конструктор по умолчанию
{
    size = 10; // по умолчанию размер множества = 10 объектам типа Matrix
    ptr = new Matrix [size]; // выделить место в памяти для множества
    for (int ix = 0; ix < size; ix++) // обнуляем множество
        for (int jx = 0; jx < getSizeMat(); jx++)
            for (int zx = 0; zx < getPtr()->getSize(); zx++)
                ptr[ix][jx][zx] = 0;
}
 
Many::Many(int manySize, int matrixSize, int arraySize) // конструктор с параметрами
{
    size = (manySize > 0 ? manySize : 10); // количество матриц
 
    ptr = new Matrix [size]; // выделить место в памяти для множества
 
    for (int ix = 0; ix < size; ix++) // перераспределяем выделенную память
        ptr[ix].setSize(matrixSize > 0 ? matrixSize : 10, arraySize > 0 ? arraySize : 10); // количество столбцов
//cout << size << "  " << ptr->getSize() << "  " << ptr->getPtr()->getSize() << std::endl;
    for (int ix = 0; ix < size; ix++) // обнуляем множество
        for (int jx = 0; jx < ptr->getSizeMat(); jx++)
            for (int zx = 0; zx < ptr->getPtr()->getSize(); zx++)
                ptr[ix][jx][zx] = 0;
//    cout << size << "  " << ptr->getSize() << "  " << ptr->getPtr()->getSize() << std::endl;
 
}
 
Many::Many(Many &manyToCopy ) // конструктор копии
    :size(manyToCopy.size)              // инициализатор размера множества
{
//    cout << size << "  " << manyToCopy.getSize() << "  " << manyToCopy.getPtr()->getSize() << std::endl;
    ptr = new Matrix [size]; // выделить место в памяти для матрицы
 
    for (int ix = 0; ix < size; ix++) // перераспределяем выделенную память
        ptr[ix].setSize(manyToCopy.getSizeRow(), manyToCopy.getSizeCol()); // количество строк и столбцов
 
    for (int ix = 0; ix < size; ix++) // обнуляем множество
        for (int jx = 0; jx < ptr->getSizeMat(); jx++)
            for (int zx = 0; zx < ptr->getPtr()->getSize(); zx++)
                ptr[ix][jx][zx] = manyToCopy[ix][jx][zx];// заполняем множество
}
 
Many::~Many() // десструктор класса Many
{
   delete  [] ptr; // освободить память, удалив матрицу
}
 
// перегруженный оператор вывода для класса Matrix (вывод элементов массива на экран)
ostream &operator<< (ostream &output, const Many &obj)
{
    if (obj.getSizeMany() == 0)
        cout << "Множество пустое!\n";
 
    for (int ix = 0; ix < obj.getSizeMany(); ix++)
    {
        for (int jx = 0; jx < obj.getSizeRow(); jx++)
        {
            for (int zx = 0; zx < obj.getSizeCol(); zx++)
            {
                output << setw(5) // под каждое число выделяется 5 позиций
                       << obj.ptr[ix][jx][zx];
            }
            cout << std::endl;
        }
        cout << std::endl << "----------------------------------------------------------------------\n";
    }
 
    output << std::endl; // перенос маркера на новую строку
 
    return output; // позволяет множественный вывод, типа cout << x << y << z << ...
}
 
// перегруженный оператор ввода, для заполнения матрицы с клавиатуры
istream &operator>> (istream & input, Many &obj)
{
    for (int ix = 0; ix < obj.size; ix++)
        for (int jx = 0; jx < obj.getSizeRow(); jx++)
            for (int zx = 0; zx < obj.getSizeCol(); zx++)
                input >> obj.ptr[ix][jx][zx]; // заполняем множество
 
    return input; // позволяет множественный ввод, типа cin >> x >> y >> z >> ...
}
 
// перегруженный оператор взятия индекса
Matrix &Many::operator[] (int subscript)
{
    if(subscript < 0 || subscript >= size)
    {
        std::cerr << "\n Ошибка индекса2: " << subscript << std::endl;
        exit(1); // завершить работу программы, неправильный индекс
    }
    return ptr[subscript]; // возврат ссылки на элемент массива
}
 
int Many::getSizeMany() const // возвратить количество элементов множества
{
    return size;
}
 
void Many::getMany() // вывод массива
{
    for (int ix = 0; ix < getSizeMany(); ix++)
    {
        for (int jx = 0; jx < getSizeRow(); jx++)
        {
            for (int zx = 0; zx < getSizeCol(); zx++)
            {
                cout << setw(5) // под каждое число выделяется 5 позиций
                       << ptr[ix][jx][zx];
            }
            cout << std::endl;
        }
        cout << std::endl << "----------------------------------------------------------------------\n";
    }
 
    cout << std::endl; // новая строка
}
 
void Many::setMany() // заполнение массива
{
    for (int ix = 0; ix < getSizeMany(); ix++)
        for (int jx = 0; jx < getSizeRow(); jx++)
            for (int zx = 0; zx < getSizeCol(); zx++)
                cin >> ptr[ix][jx][zx];       // ввод элементов множества с клавиатуры
}
 
 const Many &Many::operator= (const Many &right) // оператор присваивания
{
    if (&right != this) // чтобы не выполнялось самоприсваивание
    {
        if (size != right.getSizeMany() ||
            getSizeRow() != right.getSizeRow() || getSizeCol() != right.getSizeCol())
        {
            delete [] ptr; // освободить пространство
            size = right.getSizeMany(); // установить нужный размер множества
            ptr = new Matrix [size]; // выделить память под копируемое множество
 
            for (int ix = 0; ix < size; ix++) // перераспределяем выделенную память
                ptr[ix].setSize(right.getSizeRow(), right.getSizeCol());
        }
 
        for (int ix = 0; ix < size; ix++)
            for (int jx = 0; jx < ptr->getSizeMat(); jx++)
                for (int zx = 0; zx < ptr->getPtr()->getSize(); zx++)
                    ptr[ix][jx][zx] = right.ptr[ix][jx][zx]; // скопировать массив
    }
 
    return *this; // разрешает множественное присваивание, например x = t = e
}
 
 bool Many::operator== (const Many &right) const// оператор сравнения
 {
     if (size != right.getSizeMany() ||
         getSizeRow() != right.getSizeRow() || getSizeCol() != right.getSizeCol())
         return false; // матрицы с разным количеством элементов
 
     for (int ix = 0; ix < size; ix++)
         for (int jx = 0; jx < ptr->getSizeMat(); jx++)
             for (int zx = 0; zx < ptr->getPtr()->getSize(); zx++)
                 if (ptr[ix][jx][zx] != right.ptr[ix][jx][zx])
                     return false; // матрицы не равны
 
     return true; // матрицы равны
 }
 
 Many &Many::operator- (void) // оператор удаления элемента по номеру
 {
         Many temp(*this); // временно сохраняем текущее множество
 
         delete [] ptr; // удаляем старое множество
         size -= 1; // изменяем текущий размер
 
         ptr = new Matrix [size]; // выделить место в памяти для множества
 
         for (int ix = 0; ix < size; ix++) // перераспределяем выделенную память
             ptr[ix].setSize(temp.getSizeRow(), temp.getSizeCol()); // количество строк и столбцов
 
         for (int ix = 0; ix < size; ix++)
         {
             for (int jx = 0; jx < temp.getSizeRow(); jx++)
                 for (int zx = 0; zx < temp.getSizeCol(); zx++)
                     ptr[ix][jx][zx] = temp[ix][jx][zx];// заполняем множество
         } //конец for
 
     return *this;
 }
 
 Many Many::operator- (const Many &right) // разница двух множеств
 {
     if (size != right.getSizeMany() ||
         getSizeRow() != right.getSizeRow() || getSizeCol() != right.getSizeCol())
     {
         cout << "Множества разного размера!\n";
         exit(1); // завершить работу программы
     }
 
     Many result(*this);
     for (int ix = 0; ix < result.getSizeMany(); ix++)
         for (int jx = 0; jx < result.getSizeRow(); jx++)
             for (int zx = 0; zx < result.getSizeCol(); zx++)
                 result.ptr[ix][jx][zx] = ptr[ix][jx][zx] - right.ptr[ix][jx][zx];
 
     return result; // вернуть сумму
 }
 
 Many Many::operator+ (const Many &right) // объединение двух множеств
 {
     if (getSizeRow() != right.getSizeRow() || getSizeCol() != right.getSizeCol())
     {
         cout << "Множества разного размера!\n";
         exit(1); // завершить работу программы
     }
 
     int num = size + right.getSizeMany(); // количество элементов нового множества
 
     Many result(num, right.getSizeRow(), right.getSizeCol() );
 
     for (int ix = 0; ix < getSizeMany(); ix++)
         for (int jx = 0; jx < getSizeRow(); jx++)
             for (int zx = 0; zx < getSizeCol(); zx++)
                 result.ptr[ix][jx][zx] = ptr[ix][jx][zx];
 
     int ctr = 0;
     for (int ix = getSizeMany(); ix < result.getSizeMany(); ix++)
     {
         for (int jx = 0; jx < result.getSizeRow(); jx++)
             for (int zx = 0; zx < result.getSizeCol(); zx++)
                 result.ptr[ix][jx][zx] = right.ptr[ctr][jx][zx];
         ctr++;
     }
 
     return result; // вернуть объединенные множества
 }
 
 Many Many::operator+= (const Many &right) // объединение двух множеств
 {
     if (getSizeRow() != right.getSizeRow() || getSizeCol() != right.getSizeCol())
     {
         cout << "Множества разного размера!\n";
         exit(1); // завершить работу программы
     }
     Many temp(*this);
     delete [] ptr;
 
     size += right.getSizeMany(); // количество элементов нового множества
 
     ptr = new Matrix [size];
 
     for (int ix = 0; ix < size; ix++) // перераспределяем выделенную память
         ptr[ix].setSize(temp.getSizeRow(), temp.getSizeCol()); // количество строк и столбцов
 
     for (int ix = 0; ix < temp.getSizeMany(); ix++)
         for (int jx = 0; jx < temp.getSizeRow(); jx++)
             for (int zx = 0; zx < temp.getSizeCol(); zx++)
                 ptr[ix][jx][zx] = temp.ptr[ix][jx][zx];
 
     int ctr = 0;
     for (int ix = temp.getSizeMany(); ix < temp.getSizeMany(); ix++)
     {
         for (int jx = 0; jx < temp.getSizeRow(); jx++)
             for (int zx = 0; zx < temp.getSizeCol(); zx++)
                 ptr[ix][jx][zx] = right.ptr[ctr][jx][zx];
         ctr++;
     }
 
     return *this; // вернуть объединенные множества
 }
 
 Many Many::operator+ (const Matrix &right) // добавление элемента в множество
 {
     if (getSizeRow() != right.getSizeMat() || getSizeCol() != right.getPtr()->getSize())
     {
         cout << "Множества разного размера!\n";
         exit(1); // завершить работу программы
     }
 
//     int num = size + right.getSizeMany(); // количество элементов нового множества
 
     Many result(size + 1, right.getSizeMat(), right.getPtr()->getSize() );
 
     for (int ix = 0; ix < result.getSizeMany() - 1; ix++)
         for (int jx = 0; jx < result.getSizeRow(); jx++)
             for (int zx = 0; zx < result.getSizeCol(); zx++)
                 result.ptr[ix][jx][zx] = ptr[ix][jx][zx];
 
         for (int jx = 0; jx < result.getSizeRow(); jx++)
             for (int zx = 0; zx < result.getSizeCol(); zx++)
                 result.ptr[result.getSizeMany() - 1][jx][zx] = right.getPtr()[jx][zx];
 
     return result; // вернуть объединенные множества
 }
 
 Many &Many::operator+= (const Matrix &right) // добавление элемента в множество
 {
     if (getSizeRow() != right.getSizeMat() || getSizeCol() != right.getPtr()->getSize())
     {
         cout << "Множества разного размера!\n";
         exit(1); // завершить работу программы
     }
     Many temp(*this);
     delete [] ptr;
 
     size += 1; // количество элементов нового множества
 
     ptr = new Matrix [size];
 
     for (int ix = 0; ix < size; ix++) // перераспределяем выделенную память
         ptr[ix].setSize(temp.getSizeRow(), temp.getSizeCol()); // количество строк и столбцов
 
     for (int ix = 0; ix < temp.getSizeMany(); ix++)
         for (int jx = 0; jx < temp.getSizeRow(); jx++)
             for (int zx = 0; zx < temp.getSizeCol(); zx++)
                 ptr[ix][jx][zx] = temp.ptr[ix][jx][zx];
 
         for (int jx = 0; jx < getSizeRow(); jx++)
             for (int zx = 0; zx < getSizeCol(); zx++)
                 ptr[getSizeMany() - 1][jx][zx] = right.getPtr()[jx][zx];
 
     return *this; // вернуть объединенные множества
 }

Файл с функцией main(). В этом файле я постарался протестировать все возможности класса Many.
#include <iostream>
using namespace std;
 
#include "many.h"
 
#include <cstdlib>
 
int main()
{
    srand(time(NULL));
 
    Many tg1(4, 3, 4); // конструктор с параметрами
 
    // заполнение множества
    for (int ix = 0; ix < tg1.getSizeMany(); ix++)
        for (int jx = 0; jx < tg1.getSizeRow(); jx++)
            for (int zx = 0; zx < tg1.getSizeCol(); zx++)
                tg1[ix][jx][zx] = rand() % 100;
 
    cout << "перегруженный оператор вывода:\n" << tg1; // перегруженный оператор вывода
 
    Many tg2(tg1); // конструктор копирования
    cout << "Конструктор копирования Many tg2(tg1);:\n" << tg2;
 
//    cin >> tg2; // перегруженный оператор ввода
    cout << "Вывод множества с помощщью метода класса Many\n";
    tg2.getMany(); // вывод множества с помощщью метода класса Many
//    tg2.setMany(); // заполнение множества с помощщью метода класса Many
//    cout << tg2;
    Many tg3 = tg2; // перегруженный оператор присваивания (коснтруктор по умолчанию)
 
        cout << "Перегруженный оператор присваивания Many tg3 = tg2;\n"<< tg3;
 
        if (tg3 == tg2)
            cout << "Множества tg3 и tg2 равны!\n";
        cout << "Удаление всех элементов множества tg2\n" << -(-(-(-tg2))); // перегруженный оператор минус (удаление последнего элемента множества)
 
    cout << "Разность множеств (tg3 - tg3)\n" << (tg3 - tg3); // перегруженная операция минус (разность множеств)
 
    cout << "Объединение множеств: (tg3 + tg1)\n" << (tg3 + tg1) ; // перегруженная операция плюс (объединение множеств)
 
    tg1 +=tg3;
    cout << "Объединение множеств tg1 +=tg3;:\n" << tg1;
 
    Matrix mt1(3,4);
 
    // заполнение матрицы mt1
     for (int ix = 0; ix < mt1.getSizeMat(); ix++)
         for (int jx = 0; jx < mt1.getPtr()->getSize(); jx++)
             mt1[ix][jx] = 1; // единичная матрица
 
    cout << "tg1 + mt1\n" << (tg1 + mt1); // добавление элемента типа Matrix к множеству типа Many
 
    (tg1+=mt1)+=mt1; // перегрузка оператора сложение-присвоение
 
    cout << "Добавление элемента типа Matrix к множеству типа Many:\n" << tg1;
 
    return 0;
}
Теги:
Класс множество, трехмерный массив
Добавлено: 07 Апреля 2018 13:44:30 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...