Загрузка данных
#include <iostream>
#include <stdexcept>
using namespace std;
class Fraction {
private:
int A, B;
static int nod(int x, int y) {
if (x < 0) x = -x;
if (y < 0) y = -y;
while (y != 0) {
int t = x % y;
x = y;
y = t;
}
return x == 0 ? 1 : x;
}
void normalize() {
if (B == 0)
throw invalid_argument("Знаменатель равен нулю");
if (B < 0) {
A = -A;
B = -B;
}
int d = nod(A, B);
A /= d;
B /= d;
}
public:
Fraction() : A(0), B(1) {}
Fraction(int a, int b) : A(a), B(b) {
normalize();
}
void decompose(int& whole, Fraction& proper) const {
whole = A / B;
proper = Fraction(A % B, B);
}
Fraction operator+(const Fraction& other) const {
return Fraction(A * other.B + other.A * B, B * other.B);
}
Fraction operator-(const Fraction& other) const {
return Fraction(A * other.B - other.A * B, B * other.B);
}
Fraction operator*(const Fraction& other) const {
return Fraction(A * other.A, B * other.B);
}
Fraction operator/(const Fraction& other) const {
if (other.A == 0)
throw invalid_argument("Деление на ноль");
return Fraction(A * other.B, B * other.A);
}
Fraction& operator+=(const Fraction& other) {
*this = *this + other;
return *this;
}
Fraction& operator-=(const Fraction& other) {
*this = *this - other;
return *this;
}
Fraction& operator*=(const Fraction& other) {
*this = *this * other;
return *this;
}
Fraction& operator/=(const Fraction& other) {
*this = *this / other;
return *this;
}
friend ostream& operator<<(ostream& os, const Fraction& f) {
os << f.A;
if (f.B != 1)
os << "/" << f.B;
return os;
}
};
class Polynomial {
private:
int n; // степень полинома
double* a; // a[i] — коэффициент при x^i
public:
Polynomial() : n(0), a(new double[1]{0}) {}
Polynomial(int degree, const double coefficients[]) {
if (degree < 0)
throw invalid_argument("Отрицательная степень");
n = degree;
a = new double[n + 1];
for (int i = 0; i <= n; i++)
a[i] = coefficients[i];
update();
}
Polynomial(const Polynomial& other) {
n = other.n;
a = new double[n + 1];
for (int i = 0; i <= n; i++)
a[i] = other.a[i];
}
Polynomial(Polynomial&& other) {
// Забираем массив, оставляя в other нулевой полином.
double* empty = new double[1]{0};
n = other.n;
a = other.a;
other.n = 0;
other.a = empty;
}
~Polynomial() {
delete[] a;
}
Polynomial& operator=(const Polynomial& other) {
if (this == &other)
return *this;
double* newA = new double[other.n + 1];
for (int i = 0; i <= other.n; i++)
newA[i] = other.a[i];
delete[] a;
a = newA;
n = other.n;
return *this;
}
Polynomial& operator=(Polynomial&& other) {
if (this == &other)
return *this;
double* empty = new double[1]{0};
delete[] a;
n = other.n;
a = other.a;
other.n = 0;
other.a = empty;
return *this;
}
// Удаляет старшие члены с нулевыми коэффициентами.
void update() {
while (n > 0 && a[n] == 0)
n--;
}
double operator()(double x) const {
double result = 0;
double power = 1;
for (int i = 0; i <= n; i++) {
result += a[i] * power;
power *= x;
}
return result;
}
Polynomial& operator+=(const Polynomial& other) {
int newN = n > other.n ? n : other.n;
double* newA = new double[newN + 1];
for (int i = 0; i <= newN; i++) {
double first = i <= n ? a[i] : 0;
double second = i <= other.n ? other.a[i] : 0;
newA[i] = first + second;
}
delete[] a;
a = newA;
n = newN;
update();
return *this;
}
Polynomial& operator-=(const Polynomial& other) {
int newN = n > other.n ? n : other.n;
double* newA = new double[newN + 1];
for (int i = 0; i <= newN; i++) {
double first = i <= n ? a[i] : 0;
double second = i <= other.n ? other.a[i] : 0;
newA[i] = first - second;
}
delete[] a;
a = newA;
n = newN;
update();
return *this;
}
Polynomial& operator*=(const Polynomial& other) {
int newN = n + other.n;
double* newA = new double[newN + 1]{};
for (int i = 0; i <= n; i++)
for (int j = 0; j <= other.n; j++)
newA[i + j] += a[i] * other.a[j];
delete[] a;
a = newA;
n = newN;
update();
return *this;
}
Polynomial operator+(const Polynomial& other) const {
Polynomial result(*this);
result += other;
return result;
}
Polynomial operator-(const Polynomial& other) const {
Polynomial result(*this);
result -= other;
return result;
}
Polynomial operator*(const Polynomial& other) const {
Polynomial result(*this);
result *= other;
return result;
}
// this = quotient * divisor + remainder
void divide(const Polynomial& divisor,
Polynomial& quotient,
Polynomial& remainder) const {
if (divisor.n == 0 && divisor.a[0] == 0)
throw invalid_argument("Деление на нулевой полином");
Polynomial r(*this);
Polynomial q;
if (n >= divisor.n) {
delete[] q.a;
q.n = n - divisor.n;
q.a = new double[q.n + 1]{};
}
while (r.n >= divisor.n && !(r.n == 0 && r.a[0] == 0)) {
int power = r.n - divisor.n;
double coefficient = r.a[r.n] / divisor.a[divisor.n];
q.a[power] += coefficient;
for (int i = 0; i <= divisor.n; i++)
r.a[i + power] -= coefficient * divisor.a[i];
// Старший член вычтен полностью.
r.a[r.n] = 0;
r.update();
}
q.update();
quotient = q;
remainder = r;
}
friend ostream& operator<<(ostream& os, const Polynomial& p) {
for (int i = 0; i <= p.n; i++) {
if (i > 0) os << " + ";
os << p.a[i];
if (i > 0) os << "*x";
if (i > 1) os << "^" << i;
}
return os;
}
};
int main() {
Fraction f(7, 3);
Fraction g(1, 6);
cout << "f = " << f << endl;
cout << "f + g = " << f + g << endl;
cout << "f * g = " << f * g << endl;
int whole;
Fraction proper;
f.decompose(whole, proper);
cout << "7/3 = " << whole << " + " << proper << endl;
double first[] = {1, 0, 1}; // 1 + x^2
double second[] = {1, 1}; // 1 + x
Polynomial p(2, first);
Polynomial d(1, second);
cout << "\np(x) = " << p << endl;
cout << "d(x) = " << d << endl;
cout << "p + d = " << p + d << endl;
cout << "p * d = " << p * d << endl;
cout << "p(2) = " << p(2) << endl;
Polynomial quotient, remainder;
p.divide(d, quotient, remainder);
cout << "Частное: " << quotient << endl; // -1 + x
cout << "Остаток: " << remainder << endl; // 2
}