您的位置:首页 > 其它

一元多项式的建立及其运算

2016-02-05 14:28 316 查看
在表处理时经常遇到的问题是多项式的表示和运算。所以如何建立一个符合多项式的结构是十分重要的。(一)一元多项式的表示:一种方法是用顺序表表示,即顺序表的物理位置存储的是多项式中x的指数,而顺序表中物理位置相对应的值便是与以物理位置为指数的项的系数。但是这种方法有缺陷:对于稀疏多项式(缺很多项或是多项式的指数跳动很大)而言,将会浪费大量存储空间。在这种情况下,考虑第二方法:对于每一个系数非0的项只存储它的系数ai和指数ei,并用一个存储各系数非0项的数组来表示这个多项式。当然也可以利用链表来表示多项式。它适用于项数不定的多项式,特别是项数在运算过程中动态增长的多项式,这样即可避免存储溢出问题。其次,1:对于某些0系数项在执行加法运算后不再是0系数项,这就需要在结果多项式中增添新的项;2:对于某些非0系数项,在执行加法运算后可能是0系数项,这就需要在结果多项式中删去这些项。利用链表操作,可以简单的修改这些结点的指针以完成这种插入和删除运算。一般使用带头结点的单链表来实现一元多项式。每个节点表示多项式中的一项,命名为Term,它包括两个数据域:coef(系数)和exp(指数);a--多项式的结构定义:
#include<stdio.h>#include<iostream>using namespace std;typedef struct Term{float coef;int exp;struct Term *link;}*Polynomial;
b--一元多项式的建立算法:随意输入系数和指数,在建立新项后,按指数升序链接的链表中寻找它应插入的位置并插入。时间复杂度:O(n^2);
void Input(Polynomal &PL){//从键盘中输入一元多项式的各项,建立一个一元多项式。要求调用此函数前PL已置空Term *newTerm,*p,*pre;int c,e;while(1){cout<<"Input a term(coef,exp):"<<endl;cin>>c>>e;        //输入多项式的系数c和指数eif(e<0) break;newterm=new Term; //创建新节点if(newterm==NULL){cerr<<"动态存储失败!"<<endl; exit(1);}newTerm->coef=c;newTerm->exp=e;p=PL->link;pre=PL;while(p!=NULL&&p->exp<newTerm->exp)  //寻找新项的插入位置{pre=p;p=p->link;}if(p!=NULL&&p->exp==newTerm->exp)  //替换指数相等项的系数p->coef=newTerm->coef;else{newTerm->link=p;pre->link=newTerm;  //链入并保持项指数的升序}}}
c--输出一元多项式算法只要逐个输出多项式链表中的系数和指数即可,但输出时要注意0次项、1次项和其他项;
void Output(Polynomal &PL){//输出带头结点的一元多项式链表xTerm *p=PL->link;cout<<"The polynomal is:"<<endl;bool h=true;while(p!=NULL){if(h==false&&p->coef>0.0)cout<<"+"; //非0项不是第一项输出+h=false;cout<<p->coef;                      //输出项的系数;switch(p->exp)                      //输出项的指数;{case 0:break;                   //常数项不输出指数;case 1:cout<<"x"; break;        //一次项仅输出"x"default: cout<<"x^"<<p->exp;    //高次项输出"x^"}p=p->link;                          //下一项}cout<<endl;}
d--两个多项式的加法运算两个多项式A和B相加时假设各个多项式链表都带头结点,设置两个检测指针pa和pb分别指示在两个多项式链表中当前检测到的结点,并设结果多项式链表的头指针为C,存放指针为pe,初始位置在A的头结点。一:当pa与pb都没有检测完各自的链表时,比较当前结点的指数域:1:指数不等:小者加入C链,相应检测指针pa或pb进1;2:指数相等:对应系数相加。若相加结果不为0 ,则结果(存于pa所指的结点中)加入C链。否则不加入C链,检测指针pa与pb都进1;二:当pa或pb指针中有一个已检测完自己的链表,把另一个链表的剩余部分加入到C链中。
void AddPolynomal(Polynomal &A,Polynomal &B,Polynomal &C){//两个带头结点按升序排列的一元多项式链表的头指针分别是A和B,相加的结果通过C返回//要求C已存在且为空(链表C只有头结点存在)Term *pa,*pb,*pc,*p,*s;float temp;pc=C;pa=A->link;pb=B->link;while(pa!=NULL&&pb!=NULL){S=new Term;if(s==NULL){cerr<<"存储分配失败!"<<endl;exit(1);}if(pa->exp==pb->exp){temp=pa->coef+pb->coef;if(fabs(temp)>0.001)   //相加后系数不为0;{pc->link=s;pc=pc->link;pc->coef=temp;pc->exp=pa->exp;}pa=pa->link;pb=pb->link;}else if(pa->exp<pb->exp){pc->link=s;pc=pc->link;pc->coef=pa->coef;pc->exp=pa->exp;pa=pa->link;}else{pc->link=s;pc=pc->link;pc->coef=pb->coef;pc->exp=pb->exp;pb=pb->link;}}if(pa!=NULL)p=pa;elsep=pb;while(p!=NULL){pc->link=new Term;if(pc->link==NULL) {cerr<<"存储分配失败!"<<endl;exit(1);}pc=pc->link;pc->coef=p->coef;pc->exp=p->exp;p=p->link;}pc->link=NULL;return C;}
e--两个一元多项式相乘在实现多项式相乘的运算时,为了提高运行速度和简化程序,引入一个辅助数组result[];设两个多项式的阶分别为n和m,则辅助数组的大小等于K=(n+m),即两个相乘多项式的阶数之和,用于暂存和累加相乘后各项的结果,result[i]用于存放相乘后xi的系数。最后再顺序读出result[]的值,将它作为系数建立起结果多项式链表。算法的关键操作在于其二重嵌套循环,总的时间复杂度为O(n*m),附加空间有O(n+m);
void MultPolynomal(Polynomal &A,Polynomal &B,Polynomal &C){//将一元多项式A和B相乘,乘积用带头结点的单链表C储存Term *pa,*pb,*pc;int  AL,BL,i,k,maxExp;pc=C;for(pa=A;pa->link!=NULL;pa=pa->link)AL=pa->exp;;for(pb=B;pb->link!=NULL;pb=pb->link)BL=pb->exp;if(AL!=-1||BL!=-1){maxExp=AL+BL;float *result=new float[maxEXP+1];if(result==NULL){cerr<<"存储分配失败!"<<endl;exit(1);}memset(result,0,sizeof(result));pa=A->link;while(pa!=NULL){pb=B->link;while(pb!=NULL){k=pa->exp+pb->exp;result[k]=restul[k]+pa->coef*pb->coef;pb=pb->link;}pa=pa->link;}for(i=0;i<maxExp;i++){if(fabs[result[i]>0.001){pc->link=new Term;if(pc->link==NULL){cerr<<"存储分配失败!"<<endl;exit(1);}pc=pc->link;pc->coef=result[i];pc->exp=i;}}delete[] result;}pc->link=NULL;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: