Добавил:
CanyonE
СПбГУТ * ИКСС * Программная инженерия
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Решения лабораторных работ (местами есть ошибки) / Lab1_Polynom
.cpp#include <iostream>
#include <cmath>
#include <stdexcept>
using std::cin;
using std::cout;
using std::endl;
class Polynom {
private:
// Число степеней (отсчет с 0)
size_t n_;
// Указатель на массив с коэффициентами
double *factors_ = nullptr;
protected:
// Метод, возвращающий полином без хвоста (убирает последние члены равные 0: 0*x^21 + 0*x^22 + ... + 0*x^k)
Polynom simplify() const {
size_t i = 0;
if (n_ > 0) {
for (i = this->n_ - 1; i > 0; --i) { // Идем от конца к началу
if (this->factors_[i] != 0) { // Если встречен первый элемент != 0, то это конец полинома
break;
}
}
return Polynom(*this, i + 1);
}
return *this;
}
public:
// Конструктор
explicit Polynom(size_t n) : n_(n) {
if (n > 0) {
factors_ = new double[n] {0};
}
}
// Конструкторы копирования
Polynom(const Polynom &arg) : Polynom(arg.n_) {
n_ = arg.n_;
std::copy(arg.factors_, arg.factors_ + arg.n_, this->factors_); // Копируем коэф. из arg в this
}
Polynom(const Polynom &arg, size_t N) : Polynom(N) { // N - явное задание количества коэф.
n_ = N;
std::copy(arg.factors_, arg.factors_ + N, this->factors_); // Копируем коэф. из arg в this
}
// Оператор копирования
Polynom &operator=(const Polynom &arg) {
Polynom temp(arg); // Создаем копию arg
swap(*this, temp); // Меняем местами temp (копию arg) и this. Данные this в temp уничтожаться после return
return *this;
}
// Конструктор перемещения
Polynom(Polynom &&arg) noexcept {
n_ = arg.n_, factors_ = arg.factors_;
arg.n_ = 0, arg.factors_ = nullptr;
}
// Оператор перемещения
Polynom &operator=(Polynom &&arg) noexcept {
if (this != &arg) {
swap(*this, arg); // Меняем местами this и arg
delete[] arg.factors_, arg.factors_ = nullptr; // Освобождаем прежнюю память this (которая в arg)
arg.n_ = 0; // Количество элементов в 0
}
return *this;
}
// Деструктор
virtual ~Polynom() { delete[] factors_; }
// Стандартные операторы
//
// Получение коэффициента полинома по индексу
double &operator[](size_t k) {
return factors_[k];
}
// Вычисление значения полинома по X
double operator()(const double &x) const {
double s = 0, q = 1;
for (size_t i = 0; i < n_; ++i) {
s += this->factors_[i] * q;
q *= x;
}
return s;
}
// Операции с полиномами
//
// Сложение полиномов
Polynom operator+(const Polynom &arg) const {
size_t mx = std::max(this->n_, arg.n_), mn = std::min(this->n_, arg.n_);
Polynom result(mx); // Размер максимального из this и arg
for (size_t i = 0; i < mn; ++i) { // Идем до минимального из this и arg
result[i] = this->factors_[i] + arg.factors_[i];
}
if (arg.n_ > this->n_) { // Если один из полиномов больше (arg), то копируем данные в result из arg
std::copy(arg.factors_ + mn, arg.factors_ + mx, result.factors_ + mn);
} else { // иначе копируем данные из this
std::copy(factors_ + mn, factors_ + mx, result.factors_ + mn);
}
return result.simplify(); // Возврат упрощенного полинома
}
// Смена знака коэффициентов полинома
Polynom operator-() const {
Polynom result(n_);
for (size_t i = 0; i < n_; ++i) {
result[i] = -factors_[i];
}
return result;
}
// Вычитание полиномов
Polynom operator-(const Polynom &arg) const {
return ( *this + ( -arg ) );
}
// Умножение полиномов
Polynom operator*(const Polynom &arg) const {
size_t mx = std::max(this->n_, arg.n_), mn = std::min(this->n_, arg.n_), sz = mx + mn;
Polynom result(sz);
for (size_t i = 0; i < this->n_; ++i) {
for (size_t j = 0; j < arg.n_; ++j) {
result.factors_[i + j] += this->factors_[i] * arg.factors_[j];
}
}
return result.simplify();
}
// Производная от полинома
Polynom derivative() const {
if (this->n_ > 1) {
Polynom result(this->n_ - 1);
for (size_t i = 1; i < this->n_; ++i) {
result.factors_[i - 1] = this->factors_[i] * i;
}
return result.simplify();
}
return Polynom(1);
}
// Интеграл от полинома (C = const)
Polynom integral(double C = 0) const {
Polynom result(this->n_ + 1);
result[0] = C;
for (size_t i = 1; i < result.n_; ++i) {
result.factors_[i] = this->factors_[i - 1] / i;
}
return result.simplify();
}
// Равны ли два полинома?
bool operator==(const Polynom &arg) const {
if (n_ != arg.n_) {
return false;
}
for (size_t i = 0; i < arg.n_; ++i) {
if (this->factors_[i] != arg.factors_[i]) {
return false;
}
}
return true;
}
// Не равны ли два полинома?
bool operator!=(const Polynom &arg) const {
return !( *this == arg );
}
// Операции с числами
//
// Сложение полинома с числом
Polynom operator+(const double &d) const {
Polynom result(*this);
result.factors_[0] += d;
return result;
}
// Вычитание числа из полинома
Polynom operator-(const double &d) const {
return ( *this + ( -d ) );
}
// Умножение полинома на число
Polynom operator*(const double &d) const {
Polynom result(*this);
for (size_t i = 0; i < n_; ++i) {
result.factors_[i] *= d;
}
return ( d != 0 ? result : result.simplify() ); // Если d = 0, то упрощаем полином
}
// Деление полинома на число
Polynom operator/(const double &d) const {
return ( *this * ( 1. / d ) );
}
// Оператор приведения к типу bool
explicit operator bool () {
return n_ != 0;
}
// Дружественные функции и операторы
//
// Дружественный оператор вывода полинома в выходной поток os (cout, ...)
friend std::ostream &operator<<(std::ostream &os, const Polynom &p) {
if (p.n_ > 0) {
os << p.factors_[0];
for (size_t i = 1; i < p.n_; ++i) {
os << ' ' << ( p.factors_[i] >= 0 ? '+' : '-' ) << ' ' << fabs(p.factors_[i]) << "*x^" << i;
}
}
return os;
}
friend void swap(Polynom &first, Polynom &second) noexcept {
std::swap(first.factors_, second.factors_);
std::swap(first.n_, second.n_);
}
};
int main() {
// Полиномы 9-той степени и 11-той степени
const size_t N1 = 10, N2 = 12;
Polynom a(N1), b(N2);
for (size_t i = 0; i < N1; ++i) { a[i] = rand() % 100; }
for (size_t i = 0; i < N2; ++i) { b[i] = rand() % 100; }
// Простейшие операции с полиномами
cout << "A: " << a << endl;
cout << "A(551.): " << a(551.) << endl; // значение полинома при x = 551
cout << "B: " << b << endl;
cout << "B(551.): " << b(551.) << endl; // значение полинома при x = 551
cout << "A == B ? " << ( a == b ? "TRUE" : "FALSE" ) << endl;
cout << "A != B ? " << ( a != b ? "TRUE" : "FALSE" ) << endl;
cout << "A + B: " << a + b << endl;
cout << "A - A: " << a - a << endl;
cout << "A * 5: " << a * 5 << endl;
cout << "A / 5: " << a / 5 << endl << endl;
// Конструктор копирования (производная от полинома)
Polynom derivA(a.derivative());
cout << "A': " << derivA << endl;
// Оператор копирования (производная от полинома)
Polynom derivB = b.derivative();
cout << "B': " << derivB << endl;
// Конструктор перемещения (сумма производных двух полиномов)
Polynom derivAB(std::move(a.derivative() + b.derivative()));
cout << "A' + B': " << derivAB << endl;
// Оператор перемещения (произведение производных двух полиномов)
derivAB = std::move(a.derivative() * b.derivative());
cout << "A' * B': " << derivAB << endl << endl;
// Интегралы от полиномов
cout << "[Integral] integral(A): " << a.integral() << endl;
cout << "[Integral] integral(B): " << b.integral() << endl;
cout << "[Integral] integral(A) * integral(B): " << a.integral() * b.integral() << endl;
cout << "[Integral] integral(A * B): " << ( a * b ).integral() << endl;
}
Соседние файлы в папке Решения лабораторных работ (местами есть ошибки)