⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 poly2.h

📁 数据结构c++语言描述 Borland C++实现
💻 H
字号:

// univariate polynomials
// each polynomial is represented as a circular linked list
// with a head node

#ifndef CPolynomial_
#define CPolynomial_

#include <stdlib.h>
#include <iostream.h>
#include "xcept.h"

template <class T> class CPolynomial;

// node class
template<class T>
class PolyNode {
   friend CPolynomial<T>;
   private:
      T coeff;             // coefficient
      int exp;            // exponent
      PolyNode<T> *link;  // pointer to next node
};

// polynomial class
template<class T>
class CPolynomial {
   public:
      CPolynomial();
      ~CPolynomial() {};
      void Erase();
      int Degree()
         {if (head->link == head)
             // zero polynomial
             return 0;
          // nonzero polynomial
          return head->link->exp;
          }
      CPolynomial<T>& operator=(const CPolynomial<T>& m);
      CPolynomial<T> operator+(const CPolynomial<T>& m) const;
      CPolynomial<T> operator-(const CPolynomial<T>& m) const;
      CPolynomial<T> operator*(const CPolynomial<T>& m) const;
      CPolynomial<T> operator/(const CPolynomial<T>& m) const;
      T operator()(const T& x) const;
      void Input(istream& in);
      void Output(ostream& out) const;
   private:
      void Append(T c, int e, PolyNode<T> * &last) const;
      PolyNode<T> *head;  // pointer to head node
};

template<class T>
CPolynomial<T>::CPolynomial()
{// Create the zero polynomial.
   head = new PolyNode<T>;
   head->exp = -1;
   head->link = head;
}

template<class T>
void CPolynomial<T>::Erase()
{// Free all nodes including the head node.
   PolyNode<T> *current = head->link;
   while (current != head) {
      // free current
      PolyNode<T> *next = current->link;
      delete current;
      current = next;
      }
   // free the head node
   delete head;
   head = 0;
}

template<class T>
void CPolynomial<T>::Append(T c, int e, PolyNode<T> * &last) const
{// Add a new term with coefficient c and exponent
 // e to the right of last; update last to
 // point to the new node added.
   last->link = new PolyNode<T>;
   last = last->link;
   last->coeff = c;
   last->exp = e;
}

template<class T>
CPolynomial<T>& CPolynomial<T>::operator=(const CPolynomial<T>& p)
{// Assignment. (*this) = p.
   if (this != &p) {// not a self assignment, i.e. not p = p
                    Erase();  // free present space
                    head = new PolyNode<T>;
                    head->exp = -1;
                    PolyNode<T> *last = head;
                        // last node in *this
                    PolyNode<T> *current = p.head->link;
                    // copy nodes of p
                    while (current != p.head) {
                       Append(current->coeff, current->exp, last);
                       current = current->link;
                       }

                    // link last to head
                    last->link = head;
                    }
   return *this;
}

template<class T>
T CPolynomial<T>::operator()(const T& x) const
{// Return polynomial value at x.
   if (head->link == head)
      // zero polynomial
      return 0;

   if (!x) {// x is zero
            // find coefficient of x^0
            PolyNode<T> *current = head->link;
            while(current->link != head)
               current = current->link;
            if (current->exp)
               // no term with exponent 0
               return 0;
    
            // current points to node for x^0
            return current->coeff;
            }

   // compute highest power of x that is needed
   T PowerOfX = 1;

   for (int i = 1; i <= head->link->exp; i++)
      PowerOfX *= x;

   int CurrentPower = head->link->exp;
       // PowerOfX = x^CurrentPower

   // evlauate first term of polynomial
   PolyNode<T> *current = head->link;
   T value = current->coeff * PowerOfX;

   // add in remaining terms
   current = current->link;
   while (current != head) {
      // compute PowerOfX for this term
      for (int i = CurrentPower; i > current->exp; i--)
         PowerOfX /= x;
      CurrentPower = current->exp;

      // add in the term
      value += current->coeff * PowerOfX;

      // move to next term
      current = current->link;
      }

   return value;
}

template<class T>
CPolynomial<T> CPolynomial<T>::
          operator+(const CPolynomial<T>& p) const
{// Return w = (*this) + p.
   // define result polynomial w
   CPolynomial<T> w;
   // define cursors for w, p, and *this
   PolyNode<T> *lastw = w.head,     // last node of w
               *cp = p.head->link,  // p cursor
               *ct = head->link;    // cursor for *this

   // compute result
   while (true)
      if (ct->exp > cp->exp) {
         // higher exponent in *this
         // append ct term to w
         Append(ct->coeff, ct->exp, lastw);
         ct = ct->link;
         }
      else if (ct->exp < cp->exp) {
              // higher exponent in p
              // append cp term to w
              Append(cp->coeff, cp->exp, lastw);
              cp = cp->link;
              }
           else {
              // equal exponents, see if we are finished
              if (ct->exp == -1) {
                 // returned to head nodes
                 lastw->link = w.head;
                 return w;
                 }

              // not finished, add coeffecients
              // and append if sum is nonzero
              T sum = ct->coeff + cp->coeff;
              if (sum) Append(sum, ct->exp, lastw);
              ct = ct->link;
              cp = cp->link;
              }
}

template<class T>
CPolynomial<T> CPolynomial<T>::
          operator-(const CPolynomial<T>& p) const
{// Return w = (*this) - p.
   // define result polynomial w
   CPolynomial<T> w;
   // define cursors for w, p, and *this
   PolyNode<T> *lastw = w.head,     // last node of w
               *cp = p.head->link,  // p cursor
               *ct = head->link;    // cursor for *this

   // compute result
   while (true)
      if (ct->exp > cp->exp) {
         // higher exponent in *this
         // append ct term to w
         Append(ct->coeff, ct->exp, lastw);
         ct = ct->link;
         }
      else if (ct->exp < cp->exp) {
              // higher exponent in p
              // append cp term to w
              Append(-cp->coeff, cp->exp, lastw);
              cp = cp->link;
              }
           else {
              // equal exponents, see if we are finished
              if (ct->exp == -1) {
                 // returned to head nodes
                 lastw->link = w.head;
                 return w;
                 }

              // not finished, subtract coeffecients
              // and append if difference is nonzero
              T diff = ct->coeff - cp->coeff;
              if (diff) Append(diff, ct->exp, lastw);
              ct = ct->link;
              cp = cp->link;
              }
}

template<class T>
CPolynomial<T> CPolynomial<T>::
          operator*(const CPolynomial<T>& p) const
{// CPolynomial multiply.  Return w = (*this) * p.

   CPolynomial<T> w;  // result polynomial

   // define cursors for w, p, and *this
   PolyNode<T> *cw,                 // cursor for w
               *cp = p.head->link,  // p cursor
               *ct;                 // cursor for *this
   
   // multiply the two polynomials
   while (cp != p.head) {
      // multiply *this and cp->coeff and
      // add to w
      cw = w.head;
      ct = head->link;
      while (ct != head) {
         int e = ct->exp + cp->exp;  // exponent of new term
         T c = ct->coeff * cp->coeff;

         // find place to append new term
         while (e < cw->link->exp)
            cw = cw->link;

         if (e == cw->link->exp) {
            // add terms
            cw->link->coeff += c;
            if (cw->link->coeff) cw = cw->link;
            else {
               // coefficient is zero, remove the node
               PolyNode<T> *t = cw->link;
               cw->link = t->link;
               delete t;
               }
            }   
          else {// new exponent, insert right of cw
                PolyNode<T> *t = cw->link;
                Append(c, e, cw);
                cw->link = t;
                cw = t;
                }

          ct = ct->link;
          }
      cp = cp->link;
      }

   return w;
}

template<class T>
CPolynomial<T> CPolynomial<T>::
          operator/(const CPolynomial<T>& p) const
{// CPolynomial division.  Return w = (*this) / p.
 // Remainder is discarded.

   if (p.head->link == p.head)
      // division by zero
      throw BadInput();

   CPolynomial<T> w,  // result polynomial
                  r;  // current remainder
   r = *this;

   // define pointers to first terms in p and r
   // and to last one in w
   PolyNode<T> *fp = p.head->link,  // first in p
               *fr = r.head->link,  // first in r
               *lastw = w.head;     // last in w
   
   // divide the two polynomials
   while (fp->exp <= fr->exp) {
      // possible new term in answer
      // compute coefficient of new term
      T c = fr->coeff / fp->coeff;
      if (!c) // coefficient is zero, no more terms
         break;

      // compute exponent of new term
      int e = fr->exp - fp->exp;

      // append new term to w
      Append(c, e, lastw);

      // check if additional terms possible
      if (c * fp->coeff != fr->coeff)
         // no more terms
         break;
      
      // update remainder r by subtracting
      // p * c * x^e from r
      PolyNode<T> *cr = r.head->link;

      // term cr is eliminated
      r.head->link = cr->link;
      delete cr;
      cr = r.head;
      
      PolyNode<T> *cp = fp->link;
      while (cp != p.head) {
         // multiply term of p with c * x^e
         T NewCoeff = c * cp->coeff;
         int NewExp = e + cp->exp;
         
         // find place for this term in r
         while (NewExp < cr->link->exp)
            cr = cr->link;  // new term goes right of cr

         // see if r has a term with the same exponent
         if (NewExp == cr->link->exp) {
            // subtract terms
            cr->link->coeff -= NewCoeff;
            if (cr->link->coeff) cr = cr->link;
            else {
               // coefficient is zero, remove the node
               PolyNode<T> *t = cr->link;
               cr->link = t->link;
               delete t;
               }
            }   
         else {// new exponent, insert right of cr
               PolyNode<T> *t = cr->link;
               Append(-NewCoeff, NewExp, cr);
               cr->link = t;
               cr = t;
               }

         cp = cp->link;
         }

      fr = r.head->link;  // fr has changed
      }

   // close the list w
   lastw->link = w.head;

   return w;
}

template<class T>
void CPolynomial<T>::Input(istream& in)
{// Input the polynomial.
   // free current space
   Erase();
 
   // set up the head node
   head = new PolyNode<T>;
   head->exp = -1;
   PolyNode<T>* last = head;  // last node in *this

   // input number of terms
   cout << "Enter the number of nonzero terms" << endl;
   int terms;
   in >> terms;
   if (terms < 0) throw BadInput();
   if (terms) {// at least one nonzero term
      // input the nonzero terms in
      // decreasing order of exponents
      cout << "Enter the nonzero terms "
           << "in decreasing order of exponents."
           << endl
           << "Give input as a sequence e_1, c_1, e_2, c_2, ..."
           << endl;

      // get first term
      int exponent, LastExp;
      T coefficient;
      in >> exponent >> coefficient;
      // exponent must be >= 0 and coefficient must be nonzero
      if (exponent < 0 || !coefficient)
         throw BadInput();
      Append(coefficient, exponent, last);
      LastExp = exponent;
      
      // get remaining terms
      for (int i = 2; i <= terms; i++) {
         // get next term
         in >> exponent >> coefficient;
         if (exponent >= LastExp || !coefficient)
            throw BadInput();
         Append(coefficient, exponent, last);
         LastExp = exponent;
         }
      }
   
      // complete circular linkage
      last->link = head;
   
   return;
}

// overload >>
template<class T>
istream& operator>>(istream& in, CPolynomial<T>& x)
   {x.Input(in); return in;}


template<class T>
void CPolynomial<T>::Output(ostream& out) const
{// Output the polynomial.

   // put the exponents and coefficients into the stream out
   PolyNode<T> *current = head->link;
   while (current != head) {
      // output a term
      out << current->exp << " " << current->coeff << " ";
      current = current->link;
      }
   out << endl;
}

// overload <<
template <class T>
ostream& operator<<(ostream& out, const CPolynomial<T>& x)
   {x.Output(out); return out;}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -