📄 fpoly.cpp
字号:
/*
* C++ class to implement a polynomial type and to allow
* arithmetic on polynomials whose elements are flash numbers
*
* WARNING: This class has been cobbled together for a specific use with
* the MIRACL library. It is not complete, and may not work in other
* applications
*
* See Knuth The Art of Computer Programming Vol.2, Chapter 4.6
*/
#include "fpoly.h"
FPoly::FPoly(const FPoly& p)
{
fterm *ptr=p.start;
fterm *pos=NULL;
start=NULL;
while (ptr!=NULL)
{
pos=addterm(ptr->an,ptr->n,pos);
ptr=ptr->next;
}
}
FPoly::~FPoly()
{
fterm *nx;
while (start!=NULL)
{
nx=start->next;
delete start;
start=nx;
}
}
Flash FPoly::coeff(int power)
{
Flash c=0;
fterm *ptr=start;
while (ptr!=NULL)
{
if (ptr->n==power)
{
c=ptr->an;
return c;
}
ptr=ptr->next;
}
return c;
}
FPoly operator*(const FPoly& a,const FPoly& b)
{
FPoly prod;
fterm *iptr,*pos;
fterm *ptr=b.start;
if (&a==&b)
{ // squaring
pos=NULL;
while (ptr!=NULL)
{ // diagonal terms
pos=prod.addterm(ptr->an*ptr->an,ptr->n+ptr->n,pos);
ptr=ptr->next;
}
ptr=b.start;
while (ptr!=NULL)
{ // above the diagonal
iptr=ptr->next;
pos=NULL;
while (iptr!=NULL)
{
pos=prod.addterm(2*ptr->an*iptr->an,ptr->n+iptr->n,pos);
iptr=iptr->next;
}
ptr=ptr->next;
}
}
else while (ptr!=NULL)
{
FPoly t=a;
t.multerm(ptr->an,ptr->n);
ptr=ptr->next;
prod+=t;
}
return prod;
}
int degree(const FPoly& p)
{
return p.start->n;
}
void FPoly::clear()
{
fterm *ptr;
while (start!=NULL)
{
ptr=start->next;
delete start;
start=ptr;
}
}
FPoly &FPoly::operator=(const FPoly& p)
{
fterm *ptr,*pos=NULL;
clear();
ptr=p.start;
while (ptr!=NULL)
{
pos=addterm(ptr->an,ptr->n,pos);
ptr=ptr->next;
}
return *this;
}
FPoly& FPoly::operator+=(const FPoly& p)
{
fterm *ptr,*pos=NULL;
ptr=p.start;
while (ptr!=NULL)
{
pos=addterm(ptr->an,ptr->n,pos);
ptr=ptr->next;
}
return *this;
}
FPoly& FPoly::operator-=(const FPoly& p)
{
fterm *ptr,*pos=NULL;
ptr=p.start;
while (ptr!=NULL)
{
pos=addterm(-(ptr->an),ptr->n,pos);
ptr=ptr->next;
}
return *this;
}
void FPoly::multerm(Flash a,int power)
{
fterm *ptr=start;
while (ptr!=NULL)
{
ptr->an*=a;
ptr->n+=power;
ptr=ptr->next;
}
}
fterm* FPoly::addterm(Flash a,int power,fterm *pos)
{
fterm* newone;
fterm* ptr;
fterm *t,*iptr;
ptr=start;
iptr=NULL;
if (a.iszero()) return pos;
// quick scan through to detect if term exists already
// and to find insertion point
if (pos!=NULL) ptr=pos;
while (ptr!=NULL)
{
if (ptr->n==power)
{
ptr->an+=a;
if (ptr->an.iszero())
{ // delete term
if (ptr==start)
{ // delete first one
start=ptr->next;
delete ptr;
return start;
}
iptr=ptr;
ptr=start;
while (ptr->next!=iptr)ptr=ptr->next;
ptr->next=iptr->next;
delete iptr;
return ptr;
}
return ptr;
}
if (ptr->n>power) iptr=ptr;
else break;
ptr=ptr->next;
}
newone=new fterm;
newone->next=NULL;
newone->an=a;
newone->n=power;
pos=newone;
if (start==NULL)
{
start=newone;
return pos;
}
// insert at the start
if (iptr==NULL)
{
t=start;
start=newone;
newone->next=t;
return pos;
}
// insert new term
t=iptr->next;
iptr->next=newone;
newone->next=t;
return pos;
}
ostream& operator<<(ostream& s,const FPoly& p)
{
int first=1;
Flash a;
fterm *ptr=p.start;
if (ptr==NULL)
{
s << "0";
return s;
}
while (ptr!=NULL)
{
a=ptr->an;
if (a>0)
{
if (!first) s << " + ";
}
else s << " - ";
if (a<0) a=(-a);
if (ptr->n==0)
s << a;
else
{
if (a!=(Flash)1) s << a << "*x";
else s << "x";
if (ptr->n!=1) s << "^" << ptr->n;
}
first=0;
ptr=ptr->next;
}
return s;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -