Advertisement
maxim_shlyahtin

polynomial

Dec 20th, 2023
697
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.74 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <utility>
  4. #include <vector>
  5.  
  6. template <typename T>
  7. class Polynomial {
  8. private:
  9.     std::vector<T> coef;
  10.  
  11.     // delete leading non-significant zeros
  12.     void Delete_Front_Zeros() {
  13.         while (!coef.empty() && coef.back() == T())
  14.             coef.pop_back();
  15.     }
  16. public:
  17.     // initialize polynomial with vector of coefficients
  18.     Polynomial(const std::vector<T>& v) : coef(v) {
  19.         Delete_Front_Zeros();
  20.     }
  21.  
  22.     std::vector<T> get_coef() const{
  23.         return this->coef;
  24.     }
  25.  
  26.     void set_coef(const std::vector<T>& v){
  27.         this->coef = v;
  28.     }
  29.     // initialize constant polynomial
  30.     Polynomial(T c = T()) {
  31.         if (c != T())
  32.             coef.push_back(c);
  33.     }
  34.  
  35.     // initialize polynomial with the pair of iterators
  36.     template <typename Iter>
  37.     Polynomial(Iter first, Iter last) {
  38.         while (first != last) {
  39.             coef.push_back(*first++);
  40.         }
  41.         Delete_Front_Zeros();
  42.     }
  43.    
  44.     // returns degree of polynomial or -1 if it is zero polynomial
  45.     int Degree() const {
  46.         for (int i = coef.size() - 1; i >= 0; --i) {
  47.             if (coef[i] != T())
  48.                 return i;
  49.         }
  50.         return -1;
  51.     }
  52.  
  53.     // returns coefficient before this degree
  54.     T operator[] (size_t degree) const {
  55.         if (coef.size() > degree)
  56.             return coef[degree];
  57.         else
  58.             return T();  // returns default value if requested degree is higher than max degree
  59.     }
  60.  
  61.     // returns true if two polynomials are equal, false otherwise
  62.     bool operator == (const Polynomial<T>& other) const {
  63.         int fd = Degree();
  64.         int sd = other.Degree();
  65.         if (fd != sd) {
  66.             return false;
  67.         } else {
  68.             for (; fd >= 0; --fd) {
  69.                 if ((*this)[fd] != other[fd]) {
  70.                     return false;
  71.                 }
  72.             }
  73.             return true;
  74.         }
  75.     }
  76.  
  77.     // returns true if two polynomials are not equal, false otherwise
  78.     bool operator != (const Polynomial<T>& other) const {
  79.         return !(*this == other);
  80.     }
  81.  
  82.     // sum of two polynomials
  83.     Polynomial<T> operator + (const Polynomial<T>& other) const {
  84.         size_t pol_size = std::max(coef.size(), other.coef.size());
  85.         std::vector<T> pol(pol_size, T());  // resizing with default values
  86.         for (size_t i = 0; i != pol_size; ++i)
  87.             pol[i] = (*this)[i] + other[i];
  88.         return Polynomial<T> {pol};
  89.     }
  90.  
  91.     // difference of two polynomials
  92.     Polynomial<T> operator - (const Polynomial<T>& other) const {  
  93.         size_t pol_size = std::max(coef.size(), other.coef.size());
  94.         std::vector<T> pol(pol_size, T());
  95.         for (size_t i = 0; i != pol_size; ++i)
  96.             pol[i] = (*this)[i] - other[i];
  97.         return Polynomial<T> {pol};
  98.     }
  99.  
  100.     // product of two polynomials
  101.     Polynomial<T> operator * (const Polynomial<T>& other) const {  
  102.         size_t pol_size = coef.size() + other.coef.size();
  103.         std::vector<T> pol(pol_size, T());
  104.         for (size_t i = 0; i != coef.size(); ++i) {
  105.             for (size_t j = 0; j != other.coef.size(); ++j)
  106.                 pol[i + j] += (*this)[i] * other[j];
  107.         }
  108.         return Polynomial<T> {pol};
  109.     }
  110.  
  111.     // sum of two polynomials
  112.     Polynomial<T>& operator += (const Polynomial<T>& other) {
  113.         size_t pol_size = std::max(coef.size(), other.coef.size());
  114.         coef.resize(pol_size, T());
  115.         for (size_t i = 0; i != pol_size; ++i)
  116.             coef[i] += other[i];
  117.         Delete_Front_Zeros();
  118.         return *this;
  119.     }
  120.  
  121.     // difference of two polynomials
  122.     Polynomial<T>& operator -= (const Polynomial<T>& other) {
  123.         size_t pol_size = std::max(coef.size(), other.coef.size());
  124.         coef.resize(pol_size, T());
  125.         for (size_t i = 0; i != pol_size; ++i)
  126.             coef[i] -= other[i];
  127.         Delete_Front_Zeros();
  128.         return *this;
  129.     }
  130.  
  131.     // product of two polynomials
  132.     Polynomial& operator *= (const Polynomial<T>& other) {
  133.         Polynomial poly = *this * other;
  134.         *this = poly;
  135.         return *this;
  136.     }
  137.  
  138.     // calculates f(value)
  139.     T operator() (T value) const {  
  140.         T ans = T();
  141.         for (int i = coef.size() - 1; i >= 0; --i)
  142.             ans = coef[i] + ans * value;  // Horner's method
  143.         return ans;
  144.     }
  145.  
  146.     typename std::vector<T>::const_iterator begin() const {
  147.         return coef.begin();
  148.     }
  149.  
  150.     typename std::vector<T>::const_iterator end() const {
  151.         return coef.end();
  152.     }
  153.  
  154.     // returns composition
  155.     Polynomial<T> operator & (const Polynomial<T>& other) const {  
  156.         Polynomial<T> composition;
  157.         for (size_t i = 0; i != coef.size(); ++i) {
  158.             if (coef[i] != T()) {
  159.                 Polynomial<T> tmp{T(coef[i])};
  160.                 for (size_t j = 1; j != i + 1; ++j)
  161.                     tmp *= other;
  162.                 composition += tmp;
  163.             }
  164.         }
  165.         return composition;
  166.     }
  167.  
  168.     // divides one polynomial by another
  169.     std::pair<Polynomial<T>, T> operator / (const Polynomial<T>& other) const {
  170.         Polynomial<T> first = *this;
  171.         Polynomial<T> baza = *this;
  172.         T b = 1;
  173.         gohere:
  174.         first = baza;
  175.         std::vector<T> result(coef.size());
  176.         int fd = first.Degree();
  177.         while (fd >= other.Degree()) {
  178.             if((first[fd] * first[fd]) < (other[other.Degree()] * other[other.Degree()])){
  179.                 baza = baza * other[other.Degree()];
  180.                 b = b * other[other.Degree()];
  181.                 goto gohere;
  182.             }
  183.             T t = first[fd] / other[other.Degree()];
  184.             std::vector<T> tmp;
  185.             for (int i = 0; i != fd - other.Degree(); ++i)
  186.                 tmp.push_back(T());
  187.             tmp.push_back(t);
  188.             Polynomial<T> p {tmp};
  189.             first -= other * p;
  190.             result[fd - other.Degree()] += t;
  191.             fd = first.Degree();
  192.         }
  193.         return std::make_pair(Polynomial<T> {result}, b);
  194.     }
  195.  
  196.     // returns remainder
  197.     Polynomial<T> operator % (const Polynomial<T>& other) const {
  198.         std::pair<Polynomial<T>, T> a = (*this/ other);
  199.         return (*this * a.second) - (a.first * other);
  200.     }
  201.  
  202.     // returns PolynomialGCD (greatest common divisor)
  203.     Polynomial<T> operator , (const Polynomial<T>& other) const {  
  204.         Polynomial<T> first = *this, second = other;
  205.         if (first.Degree() < second.Degree()) {
  206.             std::swap(first, second);
  207.         }
  208.         while (second.Degree() > 0) {
  209.             Polynomial<T> tmp = second;
  210.             first = first % second;
  211.             second = first;
  212.             first = tmp;
  213.         }
  214.         if (second != T(0))
  215.             return Polynomial(T(1));
  216.         first = (first / first[first.Degree()]).first;
  217.         return first;
  218.     }
  219. };
  220.  
  221. // overload "<<" operator to print polynomials as: std::cout << polynomial;
  222. // example: x^3+2*x^2-x+3
  223. template <typename T>
  224. std::ostream& operator << (std::ostream& out, const Polynomial<T>& pol) {
  225.     int deg = pol.Degree();
  226.     if (deg == -1) {
  227.         // zero polynomial
  228.         out << '0';  
  229.     } else {
  230.         for (int i = deg; i != -1; --i) {
  231.             if (pol[i] != T(0)) {
  232.                 // printing only degree with non-zero coefficient
  233.                 if (pol[i] != T(1) && pol[i] != T(-1)) {
  234.                     if (i != deg && pol[i] > T(0)) {
  235.                         out << "+";
  236.                     }
  237.                     out << pol[i];
  238.                     if (i > 1)
  239.                         out << "*x^" << i;
  240.                     if (i == 1)
  241.                         out << "*x";
  242.                 } else if (pol[i] == T(-1)) {
  243.                     // coefficient -1 for non-zero degree prints as -
  244.                     if (i > 1)
  245.                         out << "-x^" << i;
  246.                     if (i == 1)
  247.                         out << "-x";
  248.                     if (i == 0)
  249.                         out << pol[i];
  250.                 } else if (pol[i] == T(1)) {
  251.                     if (i != deg)
  252.                         out << "+";
  253.                     if (i > 1)
  254.                         out << "x^" << i;
  255.                     if (i == 1)
  256.                         out << "x";
  257.                     if (i == 0)
  258.                         out << pol[i];
  259.                 }
  260.             }
  261.         }
  262.     }
  263.     return out;
  264. }
  265.  
  266. // int main(){
  267. //     // std::vector<int> a = {8, 0, -5, 4};
  268. //     // std::vector<int> b = {4, 2, 8};
  269. //     std::vector<int> a = {2, -1, 0, -2, 1};
  270. //     std::vector<int> b = {2, -1, -4, 0, 1};
  271. //     Polynomial t(a);
  272. //     Polynomial d(b);
  273. //     Polynomial f = (t,d);
  274. //     std::cout << t << " " << d << " " << f << std::endl;
  275.  
  276. // }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement