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
作者: DS课程组
单位: 浙江大学
时间限制: 200 ms
内存限制: 64 MB
解析:把每一次相乘的结果单独拿出来与链表连接如果是已经存在的指数就进行代数和,如果是链表中不存在的就建立新的结点来储存
以下是AC代码
#include <stdio.h>
#include <stdlib.h>
struct PolyNode {
int coef; //系数
int expon; //指数
struct PolyNode *Next;
};
typedef struct PolyNode *Node;
void Attach(int c, int e, Node *Prear);
void PrintPoly(Node Head);
Node Add(Node P1, Node P2);
Node ReadPoly();
Node Mult(Node P1, Node P2);
void Free(Node P);
int main() {
Node P1, P2, PP, PS;
P1 = ReadPoly();
P2 = ReadPoly();
PP = Mult(P1, P2);
PrintPoly(PP);
PS = Add(P1, P2);
PrintPoly(PS);
//释放空间
Free(P1);
Free(P2);
Free(PP);
Free(PS);
return 0;
}
//free函数
void Free(Node P) {
Node q = NULL;
while (P) {
q = P;
P = P->Next;
free(q);
}
}
//多项式乘法
Node Mult(Node P1, Node P2) {
Node q, p, rear;
Node t1 = P1, t2 = P2;
//有一组多项式为空时,最后乘积的多项式也必为空
if(!P1 || !P2)
return NULL;
int e, c;
//建立头结点
q = (Node)malloc(sizeof(struct PolyNode));
q->Next = NULL;
rear = q;
// 重点:用t1的第一项与t2相乘取得基础多项式
while (t2) {
Attach(t1->coef * t2->coef, t1->expon + t2->expon, &rear);
t2 = t2->Next;
}
t1 = t1->Next;
// 设计循环, 算出每一个多项式的乘积
while (t1) {
t2 = P2; //将t2重置
rear = q; //rear重置
while (t2) {
e = t1->expon + t2->expon;
c = t1->coef * t2->coef; //注意:下面两处rear->Next是否为空的判断很重要
while (rear->Next && rear->Next->expon > e) //遍历链表,寻找插入的位置
rear = rear->Next;
if (rear->Next && rear->Next->expon == e) { //指数相同
if (rear->Next->coef + c == 0) {
Node t = rear->Next;
rear->Next = t->Next;
free(t); //释放代数和为零的结点
} else
rear->Next->coef += c;
} else { //指数不同则说明出现了新的指数,把它并入到链表中
Node t = (Node)malloc(sizeof(struct PolyNode));
t->coef = c;
t->expon = e;
t->Next = rear->Next;
rear->Next = t;
}
t2 = t2->Next;
}
t1 = t1->Next;
}
p = q;
q = q->Next;
free(p); //消除头结点
return q;
}
//连接函数
void Attach(int c, int e, Node *Prear) { // 注意:此处运用二级指针
Node q;
q = (Node)malloc(sizeof(struct PolyNode));
q->coef = c;
q->expon = e;
q->Next = NULL;
(*Prear)->Next = q;
(*Prear) = q; //注意此处Prear的后移
}
// 输出多项式
void PrintPoly(Node Head) {
Node p;
if (Head == NULL)
printf("0 0\n");
else {
int flag = 1;
for (p = Head; p; p = p->Next) {
if (!flag) {
printf(" ");
} else
flag = 0;
printf("%d %d", p->coef, p->expon); //看成 %d %d 为一组输出 只有第一组不要加空格,其他组前面都有空格
}
printf("\n");
}
}
//使两条多项式相加
Node Add(Node P1, Node P2) {
Node t1, t2, p, q, rear;
q = (Node)malloc(sizeof(struct PolyNode)); //同样建立头结点
q->Next = NULL;
rear = q;
t1 = P1;
t2 = P2;
//t1和t2都不为空时就进行代数和
while (t1 && t2) {
if (t1->expon < t2->expon) {
Attach(t2->coef, t2->expon, &rear); // t1指数小于t2
t2 = t2->Next;
} else if (t1->expon > t2->expon) {
Attach(t1->coef, t1->expon, &rear); // t1指数大于t2
t1 = t1->Next;
} else { // t1指数等于t2
int num = t1->coef + t2->coef;
if (num) Attach(num, t1->expon, &rear);
t1 = t1->Next;
t2 = t2->Next;
}
}
// 有一个多项式为空时将另一条多项式剩余的项全部连接
while (t1) {
Attach(t1->coef, t1->expon, &rear);
t1 = t1->Next;
}
while (t2) {
Attach(t2->coef, t2->expon, &rear);
t2 = t2->Next;
}
p = q;
q = q->Next;
free(p); //释放头结点
return q;
}
// 建立一条多项式
Node ReadPoly() {
Node rear, p, q;
q = (Node)malloc(sizeof(struct PolyNode));
q->Next = NULL;
rear = q; //通过建立头结点来简化代码
int N, c, e;
scanf("%d", &N);
while (N--) {
scanf("%d %d", &c, &e);
Attach(c, e, &rear); //通过连接函数将多项式连起来
}
p = q;
q = q->Next;
free(p); //消除头结点
return q;
}