Многочлен из двух переменных: Суммирование, умножение, подсчёт многочлена в данной точке и его производная
недавно был на олимпиаде по программировании на языке 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 шт):
При возвращении из функций у вас создаётся новый объект класса 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;
}