Многочлен из двух переменных: Суммирование, умножение, подсчёт многочлена в данной точке и его производная

недавно был на олимпиаде по программировании на языке C++. Так вот там была одна такая задача, интересная на мой взгляд так как я только прошёл классы ,попытался развить свои способности выполнив это задание, но не тут то было.

Написать класс многочлена из двух переменных. Которая должна содержать в себе функциональность по суммирование, умножение двух многочленов, а также подсчёт многочлена в данной точке и найти его производную.

Устарело: Создал класс, который содержит два динамических массива которые хранят коэффициенты и степени переменных соответственно(первый элемент это икс, второй элемент игрек, а остальные по задумке должны были получится в процессе других действий.). Однако очень много сложностей уже при суммировании и умножении. Первая ошибка при суммировании не возвращает объект по какой то причине. Вторая ошибка при размере массивов больше двух получаю бесконечный цикл вывода, даже не смотря на само ограничение цикла. Ну и конечно букет ошибок при умножение. Мы можем получить переменную xy, у которого две разные степени, однако один и тот же коэффициент, это не ошибка но при его реализации получаю ошибки разного рода, потому мне интересен алгоритм, который позволит их хранить правильным способом , чтобы не путатся.

Что касается реализации типа это (coefx+coefy)^degree. Хз если честно, может кто-то встречал подобную задачу и это более верный вариант решения этой задачи. В целом нуждаюсь в советах и исправлениях ошибок. Заранее большое спасибо всем участникам.

Обновлено: Так, очень сильно поменял код. Теперь вместо массивов у меня матрица из коэффициентов многочлена, где индексы коэффициента и есть степени x и y.Функция суммирования и умножения готовы ,однако есть один большой минус по какой то причине деструктор уничтожает значения temp до того пока она будет возвращена. Не подскажете в чём проблема. Когда комментирую деструктор всё отлично работает.

include <iostream>
using namespace std;

class Polynom
{
private:
    double** arr;
    int xdeg, ydeg;
public:
    Polynom(int xd=1,int yd=1)
    {
        // i is degree of x and j is degree of y
        xdeg = xd;
        ydeg = yd;
        arr = new double* [xdeg+1];
        for (int i = 0; i < xdeg+1; i++)
        {
            arr[i] = new double [ydeg+1];
            
        }
        for (int i = 0; i < xdeg+1; i++)
        {
            for (int j = 0; j < ydeg+1; j++)
            {
                arr[i][j] = 0;
            }

        }
    }
    ~Polynom()
    {
        for (int i = 0; i < xdeg+1; i++)
        {
            delete[] arr[i];
        }
        delete[]arr;
    }

    Polynom operator+(const Polynom& obj)
    {
        int maxx, maxy, minx, miny;
        if (this->xdeg > obj.xdeg)
        {
            maxx = this->xdeg;
            minx = obj.xdeg;
        }
        else
        {
            maxx = obj.xdeg;
            minx = this->xdeg;
        }
        if (this->ydeg > obj.ydeg)
        {
            maxy = this->ydeg;
            miny = obj.ydeg;
        }
        else
        {
            maxy = obj.ydeg;
            miny = this->ydeg;
        }
        Polynom temp(maxx, maxy);
        for (int i = 0; i <(this->xdeg)+1; i++)
        {
            for (int j = 0; j <(this->ydeg)+1; j++)
            {
                
                temp.arr[i][j] += this->arr[i][j];
            }

        }
        for (int i = 0; i < obj.xdeg+1; i++)
        {
            for (int j = 0; j < obj.ydeg+1; j++)
            {
                temp.arr[i][j] += obj.arr[i][j];

            }

        }
    
        return temp;
       
    }

    Polynom operator*(const Polynom& obj)
    {
        Polynom temp((this->xdeg + obj.xdeg)+1, (this->ydeg + obj.ydeg)+1);

        for (int i = 0; i <this->xdeg + 1; i++)
        {
            for (int j = 0; j < this->ydeg+1; j++)
            {
                for (int k = 0; k < obj.xdeg + 1; k++)
                {
                    for (int l = 0; l < obj.ydeg + 1; l++)
                    {
                        temp.arr[i + k][j + l] += this->arr[i][j] * obj.arr[k][l];
                    }
                }
            }
        }
        return temp;
    }

    friend istream& operator>>(istream& in, Polynom& obj);
    friend ostream& operator<<(ostream& out, const Polynom& obj);
    };
    ostream& operator << (ostream& out, const Polynom& obj)
    {
        for (int i = 0; i < obj.xdeg+1 ; i++)
        {
            for (int j = 0; j < obj.ydeg+1 ;j++)
            {
                if (i == 0 && j>=1 && obj.arr[i][j]!=0 )
                {
                    out<< " + " << obj.arr[i][j] << "y^" << j ;
                }
                else if (j == 0 && i>=1 && obj.arr[i][j] != 0)
                {
                    out << " + " << obj.arr[i][j] << "x^" << i;
                }
                else if (i!=0 && j!=0 && obj.arr[i][j] != 0)
                {
                    out << " + " << obj.arr[i][j] << "(x^" << i<<")" << "*(y^" << j<<")";
                }
                else if (i ==0 && j==0 && obj.arr[i][j] != 0)
                {
                    out << obj.arr[i][j];
                }
            }
        }
        return out;


    }
    istream& operator>>(istream& in, Polynom& obj)
    {
        for (int i = 0; i < obj.xdeg+1; i++)
        {
            delete[]obj.arr[i];
        }
        delete[] obj.arr;

        cout << "Mutqagrel x-i yev y-i astijaner"  << endl;
        cin >> obj.xdeg >> obj.ydeg;
    

        obj.arr = new double* [obj.xdeg + 1];
        for (int i = 0; i < obj.xdeg+1; i++)
        {
            obj.arr[i] = new double[obj.ydeg + 1];
        }
        for (int i = 0; i < obj.xdeg+1; i++)
        {
            for (int j = 0; j < obj.ydeg+1; j++)
            {
                if (i == 0 && j >= 1 )
                {
                    cout << "Mutqagrel y-i gorcakicnere " << j << " astichani hamar" << endl;
                    cin >> obj.arr[i][j];
                }
                else if (j == 0 && i >= 1 )
                {
                    cout << "Mutqagrel x-i gorcakicnere " << i << " astichani hamar" << endl;
                    cin >> obj.arr[i][j];

                }
                else if (i != 0 && j != 0 )
                {
                    cout << "Mutqagrel x-i yev y-i gorcakicnere " << i << " yev " << j << " astichaneri hamar hamapatasxanabar" << endl;
                    cin >> obj.arr[i][j];
                }
                else if (i == 0 && j == 0)
                {
                    cout << "Mutqagrel azat andame " << endl;
                    cin >> obj.arr[i][j];
                }
                
            }
        }
        return in;
    }

    int main()
    {
        Polynom first, second, third;
        cin >> first >> second;
        third = first + second;
        cout << endl;
        cout << third << endl;
    }

Ответы (1 шт):

Автор решения: AlexGlebe

При возвращении из функций у вас создаётся новый объект класса Polynom. Функций копирования у вас нет, и создаётся грубая копия объекта. Объект из локальной переменной уничтожается и все указатели уже указывают на свободную память. Будет крах.

Решение : создать конструктор копирования. Polynom(Polynom const &) и/или, что быстрее конструктор перемещения. Polynom(Polynom &&)

Polynom(Polynom const & p)
{
    // i is degree of x and j is degree of y
    xdeg = p.xdeg;
    ydeg = p.ydeg;
    arr = new double* [xdeg+1];
    for (int i = 0; i < xdeg+1; i++)
    {
        arr[i] = new double [ydeg+1];
        
    }
    for (int i = 0; i < xdeg+1; i++)
    {
        for (int j = 0; j < ydeg+1; j++)
        {
            arr[i][j] = p.arr[i][j];
        }

    }
}

Polynom(Polynom && p)
{
    // i is degree of x and j is degree of y
    xdeg = p.xdeg; p.xdeg = 0;
    ydeg = p.ydeg; p.ydeg = 0;
    arr = p.arr; p.arr = nullptr ;
}

Возвращать копированием уже можно.

return temp;

Или с перемещением, что быстрее :

return std :: move ( temp ) ;

С деструктором пустой матрицы у вас проблема, подправил пока так :

~Polynom()
{
    if (xdeg)
      for (int i = 0; i < xdeg+1; i++)
      {
        delete[] arr[i];
      }
    delete[]arr;
}
→ Ссылка