02-线性结构2 一元多项式的乘法与加法运算 (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 <stdio.h>
#include <stdlib.h>
typedef struct PolyNode* PolyPtr;
struct PolyNode{
// expon:多项式的指数,coef多项式的系数,link是指向下一个节点的指针
int expon;
int coef;
PolyPtr link;
};
PolyPtr WritePoly()
{
// 写入一个链表,返回这个链表的头指针
PolyPtr front, rear;
int n, coef, expon;
scanf("%d", &n);
front = (PolyPtr)malloc(sizeof(struct PolyNode));
front->link = NULL;
rear = front;
while(n--){
PolyPtr p = (PolyPtr)malloc(sizeof(struct PolyNode));
scanf("%d %d", &coef, &expon);
p->coef = coef;
p->expon = expon;
p->link = NULL;
front->link = p;
front = p;
}
return rear;
}
void ReadPoly(PolyPtr tmp)
{
// 读出一个链表,若链表的第一个元素是空,则输出0 0
if(tmp->link)
{
printf("%d %d", tmp->link->coef, tmp->link->expon);
tmp = tmp->link;
while(tmp->link){
tmp=tmp->link;
printf(" %d %d", tmp->coef, tmp->expon);
}
}
else{
printf("0 0");
}
printf("\n");
}
PolyPtr mults(PolyPtr p1, PolyPtr p2)
{
// 乘法
if(!p1->link || !p2->link) {
// 如果某个链表的头指针是空的,则返回一个空的头指针
PolyPtr p = (PolyPtr)malloc(sizeof(struct PolyNode));
p->expon=0;
p->coef=0;
p->link=NULL;
return p;
}
PolyPtr result_front, result_rear, s1=p1, s2=p2;
result_front = (PolyPtr)malloc(sizeof(struct PolyNode));
result_front->link = NULL;
result_rear = result_front;
// 初始化乘法多项式,用s2的每一项乘以s1的每一项
while(s2->link)
{
PolyPtr p = (PolyPtr)malloc(sizeof(struct PolyNode));
int coef=s1->link->coef*s2->link->coef, expon=s1->link->expon+s2->link->expon;
p->coef = coef; p->expon = expon; p->link = NULL;
result_front->link = p;
result_front = p;
s2 = s2->link;
}
s1 = s1->link;
// 两重循环,用s2的每一项乘s1的每一项
while(s1->link)
{
s2 = p2;
while(s2->link)
{
result_front = result_rear;
PolyPtr p = (PolyPtr)malloc(sizeof(struct PolyNode));
int coef=s1->link->coef*s2->link->coef, expon=s1->link->expon+s2->link->expon;
p->expon = expon;
p->coef = coef;
p->link = NULL;
// 找到指数不大于当前要插入的节点的指数的位置
while(result_front->link && result_front->link->expon>expon)
result_front = result_front->link;
if(result_front->link && result_front->link->expon<expon){
// 找到了要插入的位置,并且不是链表的最后,则插入
p->link = result_front->link;
result_front->link = p;
}
else if(result_front->link && result_front->link->expon==expon)
{
if(result_front->link->coef+coef)
{
//系数相加不为0,则改变这个系数
result_front->link->coef += coef;
}
else{
//系数相加为0,则删除当前节点
PolyPtr tmp;
tmp = result_front->link;
result_front->link = tmp->link;
free(tmp);
}
}
else{
// 当前系数是最小的,要插入到这个链表的最后
result_front->link = p;
}
s2 = s2->link;
}
s1=s1->link;
}
return result_rear;
}
PolyPtr sums(PolyPtr p1, PolyPtr p2)
{
// 加法
PolyPtr result_front, result_rear;
result_front = (PolyPtr)malloc(sizeof(struct PolyNode));
result_front->link = NULL;
result_rear = result_front;
int flag;
while(p1->link && p2->link)
{
flag=1;
PolyPtr p = (PolyPtr)malloc(sizeof(struct PolyNode));
// 比较两个节点的指数的大小,插入指数较大的那个
if(p1->link->expon>p2->link->expon)
{
p->expon = p1->link->expon;
p->coef = p1->link->coef;
p1=p1->link;
}
else if(p1->link->expon<p2->link->expon)
{
p->expon = p2->link->expon;
p->coef = p2->link->coef;
p2 = p2->link;
}
else
{
if(p1->link->coef+p2->link->coef)
{
p->coef = p1->link->coef+p2->link->coef;
p->expon = p1->link->expon;
p1=p1->link;
p2=p2->link;
}
else {
flag=0;
p1=p1->link;
p2=p2->link;
}
}
if(flag)
{
result_front->link=p;
result_front=p;
}
}
// 将剩下的没有遍历完的一个链表直接链在结果后面
result_front->link = p1->link?p1->link:p2->link;
return result_rear;
}
int main()
{
PolyPtr p1, p2, mult_p, sum_p;
p1 = WritePoly();
//ReadPoly(p1);
p2 = WritePoly();
// ReadPoly(p1);
// ReadPoly(p2);
mult_p = mults(p1, p2);
ReadPoly(mult_p);
sum_p = sums(p1, p2);
ReadPoly(sum_p);
}
/*
4 3 4 -5 2 -3 1 -2 0
3 5 20 -7 4 3 1
*/