题目要求
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分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<bits/stdc++.h>
using namespace std;
typedef struct PolyNode *Polynomial;
int N;
struct PolyNode{
int coef;
int expon;
Polynomial link;
};
void Attach(int c,int e,Polynomial *pRear);
Polynomial ReadPoly(){ //读入函数
Polynomial P,Rear,t;
int c,e;
cin>>N;
P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;
Rear = P;
while(N--){
cin>>c>>e;
Attach(c,e,&Rear);
}
t = P;
P = P->link;
free(t);
return P;
}
void Attach(int c,int e,Polynomial *pRear){ //引用调用,可以改变传入参数的值
Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
P->coef = c;
P->expon = e;
P->link = NULL;
(*pRear)->link = P;
*pRear = P;
}
Polynomial Add(Polynomial P1,Polynomial P2){
Polynomial t1 = P1,t2 = P2,t,Rear;
Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));//创建加和后的链表
P->link = NULL;
Rear = P;
while(t1&&t2){
if(t1->expon==t2->expon){
if(t1->coef+t2->coef!=0) //若相加后系数为0,则直接跳过处理
Attach(t1->coef+t2->coef,t1->expon,&Rear);
t1 = t1->link;
t2 = t2->link;
}
else if(t1->expon>t2->expon){
Attach(t1->coef,t1->expon,&Rear); //指数递降规则进行新链表的构建
t1 = t1->link;
}
else{
Attach(t2->coef,t2->expon,&Rear);
t2 = t2->link;
}
}
Rear->link = t1 ? t1:t2;
t = P; //释放头节点
P = P->link;
free(t);
return P;
}
Polynomial Mult(Polynomial P1,Polynomial P2){
if(P1==NULL||P2==NULL) return NULL; //任意一个乘数为0则乘积为0
Polynomial t1 = P1,t2 = P2,t,Rear;
int c,e;
Polynomial P = (Polynomial)malloc(sizeof(struct PolyNode));
P->link = NULL;
Rear = P;
while(t2!=NULL){ //初始化乘积链表为p1的第一个元素与p2全部元素的乘积,后续代码在此基础上进行修改
Attach(t1->coef*t2->coef,t1->expon+t2->expon,&Rear);
t2 = t2->link;
}
t1 = t1->link;
while(t1!=NULL){
t2 = P2; Rear = P;
while(t2!=NULL){
c = t1->coef*t2->coef;
e = t1->expon+t2->expon;
while(Rear->link!=NULL&&Rear->link->expon>e) //找到合适的插入位置
Rear = Rear->link;
if(Rear->link!=NULL&&Rear->link->expon==e){
if(c+Rear->link->coef!=0) //判断系数和是否为0,若为0则删除该指数的节点
Rear->link->coef = c+Rear->link->coef;
else{
t = Rear->link;
Rear->link = t->link;
free(t);
}
}
else{ //若没有所乘指数的次幂,则新开创一个节点
t = (Polynomial)malloc(sizeof(struct PolyNode));
t->coef = c;
t->expon = e;
t->link = Rear->link;
Rear->link = t; Rear = Rear->link;
}
t2 = t2->link;
}
t1 = t1->link;
}
t2 = P; P = P->link ;free(t2); //释放头节点
return P;
}
void PrintPoly(Polynomial P){
int flag = 0;
if(P==NULL) {printf("0 0\n");return;}
while(P!=NULL){
if(flag==0) flag = 1; //题目中格式规定最后一个输出后面不允许有空格
else printf(" ");
cout<<P->coef<<' '<<P->expon;
P = P->link;
}
printf("\n");
}
int main(){
Polynomial P1,P2,PP,PS;
P1 = ReadPoly();
P2 = ReadPoly();
PP = Mult(P1,P2);
PrintPoly(PP);
PS = Add(P1,P2);
PrintPoly(PS);
}
用链表实现该题可以锻炼代码能力,(但是用动态数组更加简单,稍后会把数组方法补上)本题中,把一元多项式的乘法与加法写为两个函数分开处理,每次进行操作时新创建一个新链表存放结果多项式,逐项遍历处理。
我根据何老师的ppt以及伪代码完成了整个功能,因为自己第一次接触此类型题,很多判断中表达式没有简写,而是给出了对应真实含义的表达式(也是为了读者更易懂吧hh),这题的加法模块思路和合并两个链表那题比较类似,大致处理方法相同,感兴趣的朋友可以转到我的那一篇。浙大数据结构课后习题(02-线性结构1 两个有序链表序列的合并)https://blog.csdn.net/Charon_super/article/details/140263422?spm=1001.2014.3001.5501 此系列为作者记录数据结构学习文章,由于能力所限,难免有细节处理不当之处,恳请读者谅解并指正