一元多项式的乘法与加法运算 (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
思路:
- 数据存放可以用动态数组/链表;
- 加法:比较指数大小(大/同/小),系数非0则放入结果数组/链表中;
- 乘法:二重循环–非0系数项进行乘法运算(系数一定非0),通过比较指数大小将结果放入结果数组/链表中;
- 输出:通过判断返回的指针进行输出。
注意:
- 结构体中含有指针时使用typedef要注意;
- 链表尾部指针要记住处理。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct sNum {
struct sNum *prior;
int coef;
int expon;
struct sNum *next;
};
typedef struct sNum Num;
int main() {
int k, l;
Num *p1, *p2, *p3, *p4;
Num* st(int m);//函数声明
Num* multi(Num* p1, int k, Num* p2, int l);
Num* add(Num* p1, int k, Num* p2, int l);
void out(Num* p);
/*存储原始数据*/
scanf_s("%d", &k);
p1 = st(k);
scanf_s("%d", &l);
p2 = st(l);
/*运算*/
p3 = multi(p1, k, p2, l);
p4 = add(p1, k, p2, l);
/*输出*/
out(p3);
out(p4);
return 0;
}
/*存储函数*/
Num* st(int m) {
Num *head = NULL, *rear = NULL;
head = (Num*)malloc(sizeof(Num));
rear = head;
for (int i = 0; i < m; i++) {
scanf_s("%d", &rear->coef);
scanf_s("%d", &rear->expon);
if (abs(rear->coef)>1000 || abs(rear->expon)>1000) {
return NULL;//多项式非零项系数和指数(绝对值均为不超过1000的整数)
}
if (i != m - 1) {
rear->next = (Num*)malloc(sizeof(Num));
rear = rear->next;//新建一个结点,rear指向它
}
else {
rear->next = NULL;//最后一个数时,对链表作结束处理
}
}
return head;
}
/*乘法*/
Num* multi(Num* p1, int k, Num* p2, int l) {
Num* head, *rear, *temp, *t, *tp2 = p2;
int mark = 0;
head = (Num*)malloc(sizeof(Num));//声明一个空结点
rear = head;
for (int i = 0; i < k; i++) {
if (p1->coef != 0) {//p1链表的某一结点系数为0就不执行这轮乘法
for (int j = 0; j < l; j++) {
if (p2->coef != 0) {//p2链表的某一结点系数为0就不执行这轮乘法
mark++;
temp = rear;
if ((p1->expon + p2->expon) > rear->expon) {
if (mark == 1) {
rear->coef = p1->coef * p2->coef;
rear->expon = p1->expon + p2->expon;
rear->next = NULL;
rear->prior = NULL;
}
else {
do {
temp = temp->prior;
if (temp == NULL) {
break;
}
} while (temp->expon < (p1->expon + p2->expon));
if (temp->expon >(p1->expon + p2->expon)) {//插入
t = (Num*)malloc(sizeof(Num));
t->coef = p1->coef * p2->coef;
t->expon = p1->expon + p2->expon;
t->next = temp->next;
temp->next->prior = t;
temp->next = t;
t->prior = temp;
}
else if (temp->expon == (p1->expon + p2->expon)) {//计算
temp->coef = temp->coef + p1->coef * p2->coef;
// temp->expon= temp->expon + p1->expon + p2->expon;
if (temp->coef == 0) {
temp->prior->next = temp->next;
temp->next->prior = temp->prior;
free(temp);
}
}
else {//加入头
t = (Num*)malloc(sizeof(Num));
t->coef = p1->coef * p2->coef;
t->expon = p1->expon + p2->expon;
t->next = head;
head->prior = t;
head = t;
}
}
}
else if ((p1->expon + p2->expon) < rear->expon) {
rear->next = (Num*)malloc(sizeof(Num));
// temp = rear;//记录rear更改前地址
rear = rear->next;
rear->coef = p1->coef * p2->coef;
rear->expon = p1->expon + p2->expon;
rear->next = NULL;
rear->prior = temp;
}
else if ((p1->expon + p2->expon) == rear->expon) {
rear->coef = rear->coef + p1->coef * p2->coef;
// rear->expon = rear->expon+ p1->expon + p2->expon;
if (rear->coef == 0) {
// temp = rear;
rear = rear->prior;//向前更改rear
free(temp);//删除temp结点
}
}
}
p2 = p2->next;//p2指向下一个结点
}
}
p1 = p1->next;//p1指向下一个结点
p2 = tp2;//p2回到原来指向
}
if (mark==0) {
free(head);//全为零
head = NULL;
}
return head;
}
/*加法*/
Num* add(Num* p1, int k, Num* p2, int l) {
Num* head, *temp;
head = (Num*)malloc(sizeof(Num));//声明一个空结点
temp = head;
while (p1 && p2) {
if (p1->expon>p2->expon) {
if (p1->coef != 0) {
temp->next = (Num*)malloc(sizeof(Num));
temp = temp->next;
temp->coef = p1->coef;
temp->expon = p1->expon;
}
p1 = p1->next;
}
else if (p1->expon == p2->expon) {
if (p1->coef + p2->coef != 0) {
temp->next = (Num*)malloc(sizeof(Num));
temp = temp->next;
temp->coef = p1->coef + p2->coef;
temp->expon = p1->expon;
}
p1 = p1->next;
p2 = p2->next;
}
else if (p1->expon < p2->expon) {
if (p2->coef != 0) {
temp->next = (Num*)malloc(sizeof(Num));
temp = temp->next;
temp->coef = p2->coef;
temp->expon = p2->expon;
}
p2 = p2->next;
}
}
/*余下链表处理*/
for (; p1; p1 = p1->next) {
if (p1->coef != 0) {
temp->next = (Num*)malloc(sizeof(Num));
temp = temp->next;
temp->coef = p1->coef;
temp->expon = p1->expon;
}
}
for (; p2; p2 = p2->next) {
if (p2->coef != 0) {
temp->next = (Num*)malloc(sizeof(Num));
temp = temp->next;
temp->coef = p2->coef;
temp->expon = p2->expon;
}
}
/*处理链表头尾*/
temp->next = NULL;
Num* t = head;
head = head->next;
free(t);
return head;
}
/*打印*/
void out(Num* p) {
if (!p) {
printf("%d %d", 0, 0);//全为0时直接打印
}
else {
while (p) {
if (p->next != NULL) {
printf("%d %d ", p->coef, p->expon);
}
else {
printf("%d %d", p->coef, p->expon);
}
p = p->next;
}
}
printf("\n");
}