/*
Napisać komplet funkcji prowadząncych obliczenia na wielomianach.
Wielomian=Utworz(Rozmiar,Tablica_Współczynników) - tworzy i zwraca wielomian;
Zwolnij(Wielomian) - zwalnia przydzieloną pamięć;
Normalizuj(Wielomian) - usuwa zbędne zera z przodu;
Drukuj(Wielomian) - drukuje wielomian;
Wielomian=Dodaj(Wielomian_1,Wielomian_2) - dodaje dwa wielomiany;
Wielomian=Mnoz(Wielomian_1,Wielomian_2) - mnoży dwa wielomiany;

















*/
#include <iostream>

struct Wielomian
  {
   unsigned R;
   double *A;
  };

Wielomian Utworz(unsigned R,double *A=0)
  {
   Wielomian W;
   W.R=R;
   if(R)
     {
      W.A=new double[R];
      if(A) memcpy(W.A,A,R*sizeof(double));
      else memset(W.A,0,R*sizeof(double));
     }
   else W.A=0;
   return W;
  }

void Zwolnij(Wielomian &W)
  {
   if(W.R)
     {
      delete[] W.A;
      W.A=0;
      W.R=0;
     }
  }

Wielomian &Normalizuj(Wielomian &W)
  {
   unsigned R=W.R;
   while((R)&&(!W.A[R-1])) --R;
   if(R<W.R)
     {
      Wielomian V=Utworz(R,W.A);
      Zwolnij(W);
      W=V;
     }
   return W;
  }

Wielomian Dodaj(const Wielomian &X,const Wielomian &Y)
  {
   unsigned XR=X.R,YR=Y.R;
   Wielomian W=Utworz(XR>YR?XR:YR);
   for(double *a=W.A,*p,*k=(p=X.A)+XR;p<k;*(a++)+=*(p++)) {}
   for(double *a=W.A,*p,*k=(p=Y.A)+YR;p<k;*(a++)+=*(p++)) {}
   return Normalizuj(W);
  }

Wielomian Mnoz(const Wielomian &X,const Wielomian &Y)
  {
   unsigned XR=X.R,YR=Y.R;
   Wielomian W=Utworz(XR&&YR?XR+YR-1:0);
//   for(unsigned x=0;x<XR;++x)
//     {
//      for(unsigned y=0;y<YR;++y) W.A[x+y]+=X.A[x]*Y.A[y];
//     }
   double *a=W.A;
   for(double *py,*ky=(py=Y.A)+YR;py<ky;++py,a-=XR-1)
     {
      for(double *px,*kx=(px=X.A)+XR;px<kx;*(a++)+=*py**(px++)) {}
     }
   return Normalizuj(W);
  }

void Drukuj(const Wielomian &W)
  {
   bool Nic=true;
   if(W.A)
     {
      int r=W.R-1;
      for(double *p,*k=(p=W.A)+r;p<=k;--k,--r)
        {
         if(*k)
           {
            if(Nic) cout<<'(';
            if((*k>0)&&(!Nic)) cout<<'+';
            cout<<*k;
            if(r)
              {
               cout<<'x';
               if(r>1) cout<<'^'<<r;
              }
            Nic=false;
           }
        }
     }
   cout<<(Nic?'0':')');
  }

int main()
  {
   double a[]={-1,2,-3},b[]={2,-3,4,-5};
   Wielomian Z=Utworz(0);
   Drukuj(Z); cout<<endl;


   Wielomian A=Utworz(sizeof(a)/sizeof(*a),a);
   Wielomian B=Utworz(sizeof(b)/sizeof(*b),b);
   Wielomian S=Dodaj(A,B);
   Wielomian I=Mnoz(A,B);
   Drukuj(A); cout<<'+'; Drukuj(B); cout<<'='; Drukuj(S); cout<<endl;
   Drukuj(A); cout<<'*'; Drukuj(B); cout<<'='; Drukuj(I); cout<<endl;
   Zwolnij(I);
   Zwolnij(S);
   Zwolnij(B);
   I=Mnoz(A,Z);
   Drukuj(A); cout<<'*'; Drukuj(Z); cout<<'='; Drukuj(I); cout<<endl;
   Zwolnij(I);
   Zwolnij(A);
   Zwolnij(Z);
   cin.get();
   return 0;
  }
