题目
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分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 <stdio.h>
#include <malloc.h>
using namespace std;
typedef struct PolyNode *Polynomial;//结构指针,新定义的
struct PolyNode{
int coef;//系数
int expon;//指数
Polynomial link;
};
Polynomial ReadPoly();
void Attach(int c,int e,Polynomial *pRear);
Polynomial Mult(Polynomial P1 ,Polynomial P2);
Polynomial PolyAdd (Polynomial P1 ,Polynomial P2);
void PrintPoly(Polynomial P);
int Compare(int a,int b);
int main()
{
Polynomial P1,P2,PP,PS;
P1 = ReadPoly();
P2 = ReadPoly();
PP = Mult(P1,P2);
PrintPoly(PP);
printf("\n");
PS = PolyAdd(P1,P2);
PrintPoly(PS);
return 0;
}
Polynomial ReadPoly(){
Polynomial P,Rear,t;
int c,e,N;
scanf("%d",&N);
P = (Polynomial)malloc(sizeof(struct PolyNode));//申请的那个链头空结点
P->link= NULL;
Rear = P;
while(N--){
scanf("%d %d",&c,&e);
Attach(c,e,&Rear);//1.rear初值为NULL,但就必须在Attach函数中判断rear是不是NULL。2.rear初值指向空结点,Attach无需判断空与否了,但是最后一定要把这个空结点删掉
}
t= P;P=P->link;free(t);//释放那个链头空结点
return P;
}
void Attach(int c,int e,Polynomial *pRear)//这个prear是指针的指针这就是为了c语言函数能够改变参数的值所设计的。
{
Polynomial P;
P = (Polynomial)malloc(sizeof(struct PolyNode));
P->coef = c;//对新节点赋值
P->expon = e;
P->link = NULL;
(*pRear)->link = P;
*pRear = P;//修改pRear值。
}
Polynomial PolyAdd (Polynomial P1 ,Polynomial P2)
{
Polynomial front ,rear ,temp;
int sum;
rear = (Polynomial)malloc(sizeof(struct PolyNode));
front = rear;
while(P1 && P2)//当两个多像是均由非零项待处理
switch (Compare(P1->expon,P2->expon)){
case 1:
Attach(P1->coef,P1->expon,&rear);
P1 = P1->link;
break;
case -1:
Attach(P2->coef,P2->expon,&rear);
P2 = P2->link;
break;
case 0:
sum = P1->coef+P2->coef;
if(sum)Attach(sum,P1->expon,&rear);
P1 = P1->link;
P2 = P2->link;
break;
}
//将未处理完的另一个多项式的所有节点依次复制到结果多项式中去
for(;P1;P1=P1->link)Attach(P1->coef,P1->expon,&rear);
for(;P2;P2=P2->link)Attach(P2->coef,P2->expon,&rear);
rear->link=NULL;
temp = front;
front = front->link;//令front指向结果多项式第一个非零项
free(temp);//释放临时空表头结点
return front;
}
/*
乘法有两个办法,
1. 将乘法运算转换为加法运算:
将P1的当前项乘P2的各项Polynomial P1 ,Polynomial P2,再加到结果多项式里去,最后就变成了多个多项式的相加
t1 = P1;t2 = P2;
P = (Polynomial)malloc(sizeof(struct PolyNode));P->link = NULL;
Rear = P;
while(t2){
Attach(t1->Polynomial P1 ,Polynomial P2coef*t2->coef,t1->expon+t2->expon,&Rear);
t2=t2->link;
}
2.逐项插入
将P1当前项乘P2当前项,并插入到结果多项式中。关键是要找到插入位置(乘完一项就去插入)。
初始结果多项式可由P1第一项乘P2获得
*/
Polynomial Mult(Polynomial P1 ,Polynomial P2){
Polynomial P,Rear,t1,t2,t;
int c,e;
if(!P1||!P2) return NULL;//乘法嘛有一个空了就返回NULL就好。
t1 = P1;t2=P2;
P = (Polynomial)malloc(sizeof(struct PolyNode));//申请的那个链头空结点
P->link= NULL;void PrintPoly(Polynomial P);
Rear = P;
while(t2){//先用P1的第一项乘以P2,得到结果多项式的初始状态
Attach(t1->coef*t2->coef,t1->expon+t2->expon,&Rear);
t2=t2->link;
}
t1 = t1->link;
while(t1){//双重循环,就是要把t1的每一项和t2的每一项相乘。
t2 = P2;Rear = P;
while(t2){
e = t1->expon + t2->expon;
c = t1->coef*t2->coef;
while(Rear->link&& Rear->link->expon > e)
Rear = Rear->link;//这个循环退出来就代表新的节点要插在rear的后面了
//下面的if语句就是判断是合并还是插入了。
if(Rear->link&&Rear->link->expon == e){
if(Rear->link->coef+c)//合并后系数是否为0
Rear->link->coef+=c;//不为0
else{
t = Rear->link;
Rear->link = t->link;
free(t);//等于0就把那个节点删掉了
}
}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){printf("0 0");return;}
while(P){
if(!flag)
flag = 1;//细品题目的意思,其实就是第一个不输出空格,后面都是空格加指数系数,所以就这样操作。
else
printf(" ");
printf("%d %d",P->coef,P->expon);
P = P->link;
}
}
int Compare(int a,int b){
if(a>b)
return 1;
if(a==b)
return 0;
if(a<b)
return -1;
}