习题3.6 一元多项式的乘法与加法运算 (20分)
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
输出格式:
输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。
输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0
#include<iostream>
using namespace std;
struct PolyNode
{
int coef; //coifficient 系数
int expon; //exponent 指数
struct PolyNode* next;
};
typedef struct PolyNode* Polynomial;
void attachPolyNode(int c,int e,Polynomial *rear)
{
Polynomial P=new struct PolyNode;
P->coef=c;
P->expon=e;
P->next=NULL;
(*rear)->next=P; //新节点接在rear后面
*rear=P;
}
Polynomial readPoly()
{
int k,i;
cin>>k;
Polynomial P,rear;
P=new struct PolyNode; //新建链表头结点
P->next=NULL;
rear=P;
int c,e;
while(k--)
{
cin>>c>>e;
attachPolyNode(c,e,&rear); //rear在attach中会被改变
}
Polynomial t=P;
P=P->next; //P指向第一个非零项
delete t;
return P;
}
void printPoly(Polynomial P)
{
if(!P) { cout<<"0 0"<<endl;return;}
int flag=0;
while(P)
{
if(!flag)
flag=1;
else cout<<" ";
cout<<P->coef<<" "<<P->expon;
P=P->next;
}
cout<<endl;
}
Polynomial PolyAdd(Polynomial P1,Polynomial P2)
{
Polynomial Psum,rear;
Psum=new struct PolyNode;
Psum->next=NULL;
rear=Psum;
while(P1&&P2)
{
if(P1->expon>P2->expon)
{
attachPolyNode(P1->coef,P1->expon,&rear);
P1=P1->next;
}
else if(P2->expon>P1->expon)
{
attachPolyNode(P2->coef,P2->expon,&rear);
P2=P2->next;
}
else
{
if(P1->coef+P2->coef)
attachPolyNode(P1->coef+P2->coef,P1->expon,&rear);
P1=P1->next;
P2=P2->next;
}
}
if(P1) attachPolyNode(P1->coef,P1->expon,&rear);
if(P2) attachPolyNode(P2->coef,P2->expon,&rear);
Polynomial t=Psum;
Psum=Psum->next;
delete t;
return Psum;
}
Polynomial PolyMulti(Polynomial P1,Polynomial P2)
{
if(!P1||!P2) return NULL;
Polynomial rear1,rear2,P,rear,t;
P=new struct PolyNode;
P->next=NULL;
int c,e;
rear1=P1;
rear2=P2;
rear=P;
while(rear2)
{
//cout<<"遍历rear2"<<endl;
attachPolyNode(rear1->coef*rear2->coef,rear1->expon+rear2->expon,&rear);
rear2=rear2->next;
//printPoly(P);
}
rear1=rear1->next;
while(rear1)
{
//cout<<"遍历rear1"<<endl;
rear2=P2; //每次rear1更新之后,rear2从头开始相乘
rear=P; //rear也要从头开始遍历,找到合适的地方修改系数,或者尾插
while(rear2)
{
//cout<<"遍历rear2"<<endl;
c=rear1->coef*rear2->coef;
e=rear1->expon+rear2->expon;
while(rear->next&&rear->next->expon>e) //P指数从大到小,e较小时,往后查找
{
rear=rear->next;
}
if(rear->next&&rear->next->expon==e) //找到修改项
{
if(rear->next->coef+c) //如果修改后系数不为0
{
rear->next->coef+=c;
}
else //如果修改后系数为0,则删去该节点
{
t=rear->next;
rear->next=t->next;
delete t;
}
}
else //没有找到修改项,则生成新节点,并插入到rear后面(此时rear后面可能是节点或NULL)
{
Polynomial pnew=new struct PolyNode;
pnew->coef=c;
pnew->expon=e;
pnew->next=rear->next;
rear->next=pnew;
rear=rear->next; //rear指向新节点(本次遍历P2最大指数处)
}
rear2=rear2->next;
//printPoly(P);
}
rear1=rear1->next;
}
t=P;
P=P->next;
delete t;
return P;
}
int main()
{
Polynomial P1,P2,Pmulti,Psum;
P1=readPoly();
P2=readPoly();
Psum=PolyAdd(P1,P2);
Pmulti=PolyMulti(P1,P2);
printPoly(Pmulti);
printPoly(Psum);
return 0;
}