0%

02-线性结构2 一元多项式的乘法与加法运算

设计函数分别求两个一元多项式的乘积与和。

输入格式:

输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:

输出分2行,分别以指数递降方式输出乘积多项式以及和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0

输入样例:

1
2
4 3 4 -5 2  6 1  -2 0
3 5 20 -7 4 3 1

输出样例:

1
2
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

多项式结构 PolyNode - Polynomial

  1. 系数coef
  2. 指数expo
  3. 下一结点link

编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include <stdlib.h>
#include <stdio.h>

typedef struct PolyNode *Polynomial;
struct PolyNode {
// 1.系数
int coef;
// 2.指数
int expo;
// 3.下一结点
Polynomial link;
};

Polynomial ReadPoly();
void Attach(int c, int e, Polynomial *pRear);
void PrintPoly(Polynomial P);
Polynomial AddPoly(Polynomial P1, Polynomial P2);
Polynomial MultiPoly(Polynomial P1, Polynomial P2);

int main() {
Polynomial P1, P2, PP, PS;
// 1.读取输入的多项式P1
P1 = ReadPoly();
// 2.读取输入的多项式P2
P2 = ReadPoly();
// 3.多项式P1与P2相乘得PS
PS = MultiPoly(P1, P2);
PrintPoly(PS);
// 4.多项式P1与P2相乘得PP
PP = AddPoly(P1, P2);
PrintPoly(PP);

return 0;
}

Polynomial MultiPoly(Polynomial P1, Polynomial P2) {
Polynomial P, Rear, t1, t2, t;
int c,e;
if(!P1 || !P2) {
return NULL;
}
// 1.创建新链表P,存放新的多项式
P = (Polynomial)malloc(sizeof(struct PolyNode));
Rear = P;
t1 = P1;
t2 = P2;
// 2.遍历t2,将t1第一个元素乘以t2中的所有元素,得到新链表P的第1个元素
while (t2) {
// 3.指数相加,系数相乘
Attach(t1->coef * t2->coef, t1->expo + t2->expo, &Rear);
t2 = t2->link;
}
// 4.将链表t1第二个元素之后的所有元素与链表t2中的元素互乘
t1 = t1->link;
while(t1){
t2 = P2;
Rear = P;
while(t2){
// 5.指数相加,系数相乘
e = t1->expo + t2->expo;
c = t1->coef * t2->coef;
// 6.将Rear定位到P链表中指数小于e之后
while(Rear->link && Rear->link->expo > e) {
Rear = Rear->link;
}
// 7.定位到多项式系数相等的结点
if (Rear->link && Rear->link->expo == e) {
// 8.还需要判断系数相加后是否为0,为0需要移除该结点
if (Rear->link->coef + c){
Rear->link->coef += c;
} else {
t = Rear->link;
Rear->link = t->link;
free(t);
}
} else {
// 9.如果多项式指数不相等,生成新的结点将新的指数、系数写入结点t
// Attach(c, e, &Rear);
t = (Polynomial)malloc(sizeof(struct PolyNode));
t->coef = c;
t->expo = e;
// 10.将新结点t插入链表的尾部,尾指针Rear指向t
t->link = Rear->link;
Rear->link = t;
Rear = Rear->link;
}
// 11. 链表t2指向下一结点
t2 = t2->link;
}
// 12.链表t1指向下一结点
t1 = t1->link;
}
Rear->link = NULL;
t2 = P;
// 13.释放链表P的空的头结点
P = P->link;
free(t2);
return P;
}

Polynomial AddPoly(Polynomial P1, Polynomial P2) {
if (P1 == NULL && P2 == NULL) {
return NULL;
}
Polynomial front, rear, temp;
int sum, result;
// 1.创建新的链表rear
rear = (Polynomial)malloc(sizeof(struct PolyNode));
front = rear;
// 2.遍历链表P1,P2
while(P1 && P2) {
result = P1->expo - P2->expo;
// 3.比较P1,P2结点指数,将较小者插入链表尾部
if (result > 0) {
Attach(P1->coef, P1->expo, &rear);
P1 = P1->link;
} else if (result < 0) {
Attach(P2->coef, P2->expo, &rear);
P2 = P2->link;
} else {
// 4.如果两结点的指数相等,两结点相加
sum = P1->coef + P2->coef;
// 5.如果系数不为0,将新结点插入rear尾部
if (sum) {
Attach(sum, P1->expo, &rear);
}
// 6.链表P1,P2指向下一个结点
P1 = P1->link;
P2 = P2->link;
}
}
// 7.处理未对比完成的剩余段
for(;P1;P1=P1->link)Attach(P1->coef, P1->expo, &rear);
for(;P2;P2=P2->link)Attach(P2->coef, P2->expo, &rear);
rear->link = NULL;
temp = front;
// 8.释放链表rear的空的头结点
front = front->link;
free(temp);
return front;
}

Polynomial ReadPoly() {
int N, e, c;
Polynomial P, Rear, t;
scanf("%d", &N);
// 1.动态申请多项式临时结点P,方便链表尾部插入新结点
P = (Polynomial) malloc(sizeof(struct PolyNode));
P->link = NULL;
Rear = P;
while (N--) {
// 2.读取多项式的系数与指数,并插入链表P的尾部
scanf("%d %d", &c, &e);
Attach(c, e, &Rear);
}
t = P;
// 3.删除临时生成的头结点P
P = P->link;
free(t);
return P;
}

void Attach(int c, int e, Polynomial *pRear) {
Polynomial P;
// 1.动态申请多项式结点,并插入pRear尾结点
P = (Polynomial) malloc(sizeof(struct PolyNode));
P->coef = c;
P->expo = e;
P->link = NULL;
(*pRear)->link = P;
// 2.修改的pRear的值,指向刚创建的结点P
*pRear = P;
}

void PrintPoly(Polynomial P) {
int flag = 0;
if (!P) {
printf("0 0\n");
return;
}
while (P) {
if (!flag) {
flag = 1;
} else {
printf(" ");
}
printf("%d %d", P->coef, P->expo);
P = P->link;
}
printf("\n");
}

小结:

  1. 链表尾插入,可以先创建空的头结点方便操作,最后再释放头结点
  2. 链表尾插入,需要定义尾指针Rear,新结点插入完成后,Rear指向新结点