题目
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分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。
甚至一开始算加法多项式时,我将list1和list2的节点直接插入到结果多项式中,破坏了链表的结构,导致求乘法多项式一直得不到想要的数据。
刷提前理清思路真的很重要,以后再也不会一上来就直接写代码了。
1、加法多项式
题目给出的输入已经按照降幂顺序排列好,相加时不需要考虑顺序的问题,同时加法也不需要考虑同类项合并,但加法需要考虑系数互为相反数的项相加为0的情况。
运算思路:
分别令p
和q
指向list1
和list2
(即两个多项式)的第一项数据
当p的指数大于q
的指数,将节点p复制给新节点newNode
,将newNode
移动到result
的末尾,p
往后移动,q
不动
当p
的指数小于q
的指数,将节点q
复制给新节点newNode
,将newNode
移动到result
的末尾,q
往后移动,p
不动
当p
的指数等于q
的指数,若p
和q
的系数相加不为0,则复制到结果多项式,为0则舍弃。之后p
和q
都要向后移动
如果p
或q
还有剩余的节点,直接接到结果多项式的末尾
如果给出的输入,所以项全部抵消了,或本身给出的输入就是零多项式,此时结果多项式为空表,输出0 0
2、乘法多项式
乘法不用考虑相乘系数为0的情况,但需要考虑顺序和同类项合并的问题。
用二重循环得到多项式相乘的所有结果
将每个结果节点newNode
插入到结果多项式中合适的位置(按照指数降序排列)文章来源:https://www.toymoban.com/news/detail-728647.html
- 先找到正确的插入位置,从结果多项式开头按顺序查找,找到第一个小于等于自己系数的项
- 如果小于,直接插入
- 如果等于,则要合并同类项,要记得判断合并后的系数是否为0,是则删除这个项
动图来源文章来源地址https://www.toymoban.com/news/detail-728647.html
代码
#include <stdio.h>
#include <stdlib.h>
typedef struct Node
{
int coefficient; //系数
int exponent; //指数
struct Node *next;
} Node, *LinkList;
void initList(LinkList *head)
{
if ((*head = (LinkList)malloc(sizeof(Node))) == NULL)
exit(-1);
(*head)->next = NULL;
}
void creatList(LinkList head)
{
LinkList p, tail = head;
int count;
scanf("%d", &count);
while (count-- > 0)
{
p = (LinkList)malloc(sizeof(Node));
scanf("%d%d", &p->coefficient, &p->exponent);
tail->next = p;
tail = p;
}
tail->next = NULL;
}
void printList(LinkList head)
{
LinkList p = head->next;
while (p)
{
if (p == head->next)
printf("%d %d", p->coefficient, p->exponent);
else
printf(" %d %d", p->coefficient, p->exponent);
p = p->next;
}
}
void addition(LinkList list1, LinkList list2)
{
LinkList result, p = list1->next, q = list2->next, tail, newNode;
initList(&result);
tail = result;
while (p && q)
{
int coefficient1, coefficient2, exponent1, exponent2;
newNode = (LinkList)malloc(sizeof(Node));
// 当p的指数大于q的指数,将节点p复制给newNode,将newNode移动到result的末尾,p往后移动,q不动
if (p->exponent > q->exponent)
{
newNode->coefficient = p->coefficient;
newNode->exponent = p->exponent;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
p = p->next;
}
else if (p->exponent < q->exponent)
{
// 当p的指数小于q的指数,将节点q复制给newNode,将newNode移动到result的末尾,q往后移动,p不动
newNode->coefficient = q->coefficient;
newNode->exponent = q->exponent;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
q = q->next;
}
else
{
// 当p和q的指数相等,直接将两个的系数相加。如果相加后的系数为0,则将p,q直接移动到下一位
if (p->coefficient + q->coefficient == 0)
{
p = p->next;
q = q->next;
free(newNode);
}
else
{
newNode->coefficient = p->coefficient + q->coefficient;
newNode->exponent = p->exponent;
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
p = p->next;
q = q->next;
}
}
}
// 如果p或q还有剩余节点,直接接到result的末尾
if (!p)
{
tail->next = q;
}
if (!q)
{
tail->next = p;
}
if (!result->next)
{
free(result);
printf("0 0");
}
else
{
printList(result);
}
}
void multiplication(LinkList list1, LinkList list2)
{
LinkList result, p = list1->next, q , tail, newNode;
initList(&result);
tail = result;
while (p)
{
q = list2->next;
while (q)
{
// 创建新建的newNode
newNode = (LinkList)malloc(sizeof(Node));
newNode->coefficient = p->coefficient * q->coefficient;
newNode->exponent = p->exponent + q->exponent;
newNode->next = NULL;
LinkList temp = result;
// 找到合适的插入位置
while (temp->next && newNode->exponent < temp->next->exponent)
{
temp = temp->next;
}
// 插入或者合并同类项
if (temp->next == NULL || newNode->exponent > temp->next->exponent)
{
newNode->next = temp->next;
temp->next = newNode;
}
else if (newNode->exponent == temp->next->exponent)
{
temp->next->coefficient += newNode->coefficient;
// 如果合并同类项后系数为0,得删除这个节点
if(!temp->next->coefficient){
LinkList deleteNode=temp->next;
temp->next=deleteNode->next;
free(deleteNode);
}
free(newNode);
}
q = q->next;
}
p = p->next;
}
if (!result->next)
{
free(result);
printf("0 0");
}
else
{
printList(result);
}
}
int main()
{
LinkList list1, list2;
initList(&list1);
initList(&list2);
creatList(list1);
creatList(list2);
multiplication(list1, list2);
printf("\n");
addition(list1, list2);
return 0;
}
到了这里,关于PTA 习题3.6 一元多项式的乘法与加法运算的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!