1.实验目的
熟练掌握链式线性表的基本操作,以及在多项式运算上的应用。
2.实验内容
设计函数分别求两个一元多项式的乘积与和。
3.实验要求
(1)输人说明:输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。
(2)输出说明:输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。
(3)测试用例:
序号 输入 输出 说明
1 请输入多项式非零项的个数:4
请以指数递降方式输入多项式非零项的系数和指数:3 4 -5 2 6 1 -2 0
请输入多项式非零项的个数:3
请以指数递降方式输入多项式非零项的系数和指数:5 20 -7 4 3 1 进行加法运算后的多项式的系数和指数(以指数递降顺序输出):5 20 -4 4 -5 2 9 1 -2 0
进行乘法运算后的多项式的系数和指数(以指数递降顺序输出):15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1 一般情况
2 请输入多项式非零项的个数:2
请以指数递降方式输入多项式非零项的系数和指数:1 2 1 0
请输入多项式非零项的个数:2
请以指数递降方式输入多项式非零项的系数和指数:1 2 -1 0 进行加法运算后的多项式的系数和指数(以指数递降顺序输出):2 2
进行乘法运算后的多项式的系数和指数(以指数递降顺序输出):1 4 -1 0 同类项合并时有抵消
3 请输入多项式非零项的个数:2
请以指数递降方式输入多项式非零项的系数和指数:-1000 1000 1000 0
请输入多项式非零项的个数:2
请以指数递降方式输入多项式非零项的系数和指数:1000 1000 -1000 0 进行加法运算后的多项式的系数和指数(以指数递降顺序输出):0 0
进行乘法运算后的多项式的系数和指数(以指数递降顺序输出):-1000000 2000 2000000 1000 -1000000 0 结果有零多项式
4 请输入多项式非零项的个数:0
请以指数递降方式输入多项式非零项的系数和指数:
请输入多项式非零项的个数:1
请以指数递降方式输入多项式非零项的系数和指数:999 1000 进行加法运算后的多项式的系数和指数(以指数递降顺序输出):999 1000
进行乘法运算后的多项式的系数和指数(以指数递降顺序输出):0 0 输入有零多项式和常数多项式
4.解决思路
(1)问题分析
由于多项式可能非常稀疏,所以宜采用链式线性表表示,仅存储非零项。又由于题目不仅要求计算乘积,还要求计算和式,所以在计算中不能破坏原始输入的两个多项式,需要建立新的链表存储结果多项式。
多项式的加法运算很简单,只要逐项比较两多项式的非零项,将指数较大的项加到结果多项式的末尾即可。这里要注意指数相同的项相加后系数为零的情况,以及零多项式的特殊处理。
对于两个多项式P1和P2相乘,可有两种求解思路:
①利用多项式的加法运算,即将多项式P2的每一项分别与P1多项式相乘,其结果也是一个多项式。应用多项式的加法运算,逐步将这些多项式累加,就可获得结果。
②直接运算,逐项插入。将多项式P2的每一项分别与P1各项相乘,将所乘形成的新项插人到中间结果多项式中。该中间结果多项式一开始为空,并以指数递减的顺序维持当前的运算中间状态。当有新项需要插人时,相当于在一个递减链表中插入一个新结点,并维持递减顺序。如果插入的新结点的指数与链表中某结点的指数一样,则将其系数相加;如果系数相加后的结果为零,则从中间结果链表中删除相应结点,否则就更改链表中系数值;如果不存在指数相同结点,则将新结点插入到相应位置。
(2)实现要点
不管是采用上述哪种方法,都需要使用一个链表P表示当前运算的中间状态(也是一个多项式),P一开始是空的。 如果直接使用多项式加法运算,则每次将P2的某项与Pl相乘的结果生成一个新多项式TmpP,然后将TmpP加到P中,使P保持目前的运算结果。如果采用直接插入各项的方法,则是将P2的某项与P1的某项相乘的结果(系数相乘,指数相加),按顺序插入到P中。
注意:采用模块化编程,将求和函数与求乘积函数分别实现,会带来很大方便。
5.实验思考题
本题以链表的方式表示多项式,读者可以改用数组的方式实现相应的多项式乘法与加法运算。
6.数据结构及相关函数说明
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int coef; //系数
int expon; //指数
struct Node *next; //指向下一个结点的指针
}PolyNode;
typedef PolyNode *PtrToNode; //指向结点的指针
typedef PolyNode *Polynomial; //指向多项式的指针
Polynomial ReadPoly() //读入多项式
{
Polynomial head,t,p; //创建链表用以下多次用到,同上表示
head=t=p=NULL;
int n,x,y;
scanf("%d",&n);
while(n--){
scanf("%d%d",&x,&y);
p=(Polynomial)malloc(sizeof(PolyNode));
p->coef=x;
p->expon=y;
p->next=NULL;
if(head==NULL)head=p;
else t->next=p;
t=p;
}
return head;
}
void PrintPoly(Polynomial p){ //多项式输出
if(p == NULL){
printf("0 0");
}
while(p)
{
if(p->next)
printf("%d %d ",p->coef,p->expon);
else printf("%d %d",p->coef,p->expon);
p=p->next;
}
printf("\n");
}
Polynomial AddPoly(Polynomial p1,Polynomial p2){
Polynomial head,p,t; //同上
head=p=t=NULL;
while(p1&&p2){
if(p1->expon<p2->expon){
p=(Polynomial)malloc(sizeof(PolyNode)); //将指数大的结点先加到链表中
p->coef=p2->coef;
p->expon=p2->expon;
p->next=NULL;
if(head==NULL)head=p;
else t->next=p;
t=p;
p2=p2->next;
}
else if(p1->expon>p2->expon){ //同上
p=(Polynomial)malloc(sizeof(PolyNode));
p->coef=p1->coef;
p->expon=p1->expon;
p->next=NULL;
if(head==NULL)head=p;
else t->next=p;
t=p;
p1=p1->next;
}
else{ //指数相同则相加
int sum=p1->coef+p2->coef;
if(sum!=0){
p=(Polynomial)malloc(sizeof(PolyNode)); //每次添加结点都用样的方法
p->coef=sum;
p->expon=p1->expon;
p->next=NULL;
if(head==NULL)head=p;
else t->next=p;
t=p;
}
p1=p1->next;
p2=p2->next;
}
}
if(p1!=NULL){
if(head==NULL)head=p1;
else t->next=p1;
t=p1;
}
else{
if(head==NULL)head=p2;
else t->next=p2;
t=p2;
}
return head;
}
Polynomial MultiPoly(Polynomial p1,Polynomial p2){
Polynomial head,p,t;
head=p=t=NULL;
Polynomial t2=p2; //用于遍历p2
Polynomial T1,T2;//两个链表用于储存每次相乘得到的链表,再用于相加
T1=T2=NULL;
if(p1&&p2){}
else return NULL;//其中一表为空,便返回NULL
while(t2!=NULL){ //先建好T1,后面T2就可以在循环中实现了
int x,y;
x=t1->coef*t2->coef;
y=t1->expon+t2->expon;
p=(Polynomial)malloc(sizeof(PolyNode));
p->coef=x;
p->expon=y;
p->next=NULL;
if(T1==NULL)T1=p;
else t->next=p;
t=p;
t2=t2->next;
}
t1=t1->next;
while(t1){
T2=p=t=NULL;
t2=p2;
while(t2!=NULL){//每次都建立一个T2
int x,y;
x=t1->coef*t2->coef;
y=t1->expon+t2->expon;
p=(Polynomial)malloc(sizeof(PolyNode));
p->coef=x;
p->expon=y;
p->next=NULL;
if(T2==NULL)T2=p;
else t->next=p;
t=p;
t2=t2->next;
}
T1 = AddPoly( T1, T2 );//每次都将得到的两个链表先加起来
t1=t1->next;
}
return T1;
}
int main()
{
Polynomial P1, P2, PA, PM;
P1 = ReadPoly();
P2 = ReadPoly();
PA = AddPoly( P1, P2 );
PrintPoly( PA );
PM = MultiPoly( P1, P2 );
// PrintPoly(P1);
// PrintPoly(P2);
PrintPoly(PM);
}