180 lines
5.5 KiB
C
180 lines
5.5 KiB
C
#include "poly_calc.h"
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <stdbool.h>
|
||
|
||
// Возведение полинома в целую степень
|
||
Polynomial deg_poly(Polynomial *p, int degree) {
|
||
Polynomial result; init_polynomial(&result);
|
||
Polynomial temp = copy_poly(p);
|
||
for (int i = 1; i < degree; i++) {
|
||
Polynomial new_result = mul_polynomials(&temp, p);
|
||
free_polynomial(&temp);
|
||
temp = new_result;
|
||
}
|
||
result = temp;
|
||
return result;
|
||
}
|
||
|
||
// Возвращает копию полинома
|
||
Polynomial copy_poly(Polynomial *p) {
|
||
Polynomial result; init_polynomial(&result);
|
||
for (int i = 0; i < p->size; ++i) {
|
||
add_term(&result, p->terms[i].coefficient, p->terms[i].exponent);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
Polynomial mul_polynomials(Polynomial *p1, Polynomial *p2) {
|
||
Polynomial result; init_polynomial(&result);
|
||
|
||
for (int i = 0; i < p1->size; ++i) {
|
||
for (int j = 0; j < p2->size; ++j) {
|
||
Term t1 = p1->terms[i];
|
||
Term t2 = p2->terms[j];
|
||
|
||
// Результат перемножения двух слагаемых
|
||
Term res_t;
|
||
res_t.coefficient = t1.coefficient * t2.coefficient;
|
||
res_t.exponent = t1.exponent + t2.exponent;
|
||
|
||
// Прибавление полученного результата (слагаемого)
|
||
// к результирующему полиному
|
||
add_term_and_poly(&result, res_t);
|
||
}
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
Polynomial sub_polynomials(Polynomial *p1, Polynomial *p2) {
|
||
for (int i = 0; i < p2->size; ++i) {
|
||
p2->terms[i].coefficient *= -1;
|
||
}
|
||
return add_polynomials(p1, p2);
|
||
}
|
||
|
||
// Cложение полиномов
|
||
Polynomial add_polynomials(Polynomial *p1, Polynomial *p2) {
|
||
Polynomial result; init_polynomial(&result);
|
||
|
||
for (int i = 0; i < p1->size; ++i) {
|
||
add_term_and_poly(&result, p1->terms[i]);
|
||
}
|
||
|
||
for (int i = 0; i < p2->size; ++i) {
|
||
add_term_and_poly(&result, p2->terms[i]);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
// Сложение одного слагаемого и полинома
|
||
void add_term_and_poly(Polynomial *p, Term term) {
|
||
Term* t = exist_incremental(p, term);
|
||
if (t) {
|
||
t->coefficient += term.coefficient;
|
||
} else {
|
||
add_term(p, term.coefficient, term.exponent);
|
||
}
|
||
}
|
||
|
||
// Например есть полином x+1 и терм (2,1)=2x, значит в полиноме есть
|
||
// incremental (увеличиваемое), т.е. есть к чему прибавить 2x
|
||
Term* exist_incremental(Polynomial *p, Term term) {
|
||
for (int i = 0; i < p->size; ++i) {
|
||
if (p->terms[i].exponent == term.exponent) {
|
||
return &p->terms[i];
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
// Инициализация полинома
|
||
void init_polynomial(Polynomial *p) {
|
||
p->size = 0;
|
||
p->capacity = 4;
|
||
p->terms = (Term *)malloc(p->capacity * sizeof(Term));
|
||
if (!p->terms) {
|
||
perror("Memory allocation failed");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
}
|
||
|
||
// Добавление слагаемого в полином
|
||
void add_term(Polynomial *p, int coeff, int exp) {
|
||
// Проверяем, нужно ли расширить массив
|
||
if (p->size >= p->capacity) {
|
||
p->capacity *= 2;
|
||
p->terms = (Term *)realloc(p->terms, p->capacity * sizeof(Term));
|
||
if (!p->terms) {
|
||
perror("Memory reallocation failed");
|
||
exit(EXIT_FAILURE);
|
||
}
|
||
}
|
||
|
||
// Добавляем слагаемое
|
||
p->terms[p->size].coefficient = coeff;
|
||
p->terms[p->size].exponent = exp;
|
||
p->size++;
|
||
}
|
||
|
||
// Сортировка слагаемых в полиноме по убыванию степени
|
||
void sort_polynomial(Polynomial *p) {
|
||
for (int i = 0; i < p->size - 1; i++) {
|
||
for (int j = 0; j < p->size - i - 1; j++) {
|
||
if (p->terms[j].exponent < p->terms[j + 1].exponent) {
|
||
// Обмен слагаемых
|
||
Term temp = p->terms[j];
|
||
p->terms[j] = p->terms[j + 1];
|
||
p->terms[j + 1] = temp;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Освобождение памяти, занятой полиномом
|
||
void free_polynomial(Polynomial *p) {
|
||
free(p->terms);
|
||
p->terms = NULL;
|
||
p->size = 0;
|
||
p->capacity = 0;
|
||
}
|
||
|
||
// Печать полинома
|
||
void print_polynomial(Polynomial *p, char letter) {
|
||
if (p->size == 0) {
|
||
printf("0\n");
|
||
return;
|
||
}
|
||
|
||
for (int i = 0; i < p->size; i++) {
|
||
Term term = p->terms[i];
|
||
|
||
if (term.coefficient == 0) {
|
||
continue;
|
||
}
|
||
|
||
// Печать знака (не печатаем '+' перед первым слагаемым)
|
||
if (i != 0 || term.coefficient < 0) {
|
||
printf("%c", term.coefficient > 0 ? '+' : '-');
|
||
}
|
||
|
||
// Печать коэффициента (если не 1/-1 или если степень 0)
|
||
if (abs(term.coefficient) != 1 || term.exponent == 0) {
|
||
printf("%d", abs(term.coefficient));
|
||
} else if (term.coefficient == -1 && term.exponent != 0) {
|
||
printf("-"); // Специальный случай для -x^n
|
||
}
|
||
|
||
// Печать переменной
|
||
if (term.exponent > 0) {
|
||
printf("%c", letter);
|
||
// Печать степени только если она больше 1
|
||
if (term.exponent > 1) {
|
||
printf("^%d", term.exponent);
|
||
}
|
||
}
|
||
}
|
||
printf("\n");
|
||
} |