设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分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 Node
{
int coefficient;
int exponent;
struct Node* Next;
}*List;
List CreateList(void);
void IntoList(List L);
void InList(List L, List P);
List AddList(List L1, List L2);
List MultiplyList(List L1, List L2);
void OutList(List L);
int main(void)
{
List L1, L2;//创建两个存放多项式的链表
L1 = CreateList();
L2 = CreateList();
IntoList(L1);//先输入第一个多项式
IntoList(L2);//再输入第二个多项式
List Add,Mult;//相加后的多项式Add和相乘后的多项式Mult
Add= AddList( L1->Next, L2->Next);
Mult = MultiplyList(L1->Next, L2->Next);
OutList(Mult->Next);//输出相乘后的多项式
printf("\n");
OutList(Add->Next);//输出相加后的多项式
return 0;
}
/*创建一个新的链表*/
List CreateList(void)
{
List L = NULL;
L = (List)malloc(sizeof(struct Node));//为新的链表申请一个空间
L->Next = NULL;
return L;//返回头结点
}
/*存入待处理的多项式*/
void IntoList(List L)
{
List pri, pre;
int number;//多项式的项数
/*找到L的链尾*/
pri = L;
while (pri->Next != NULL)
pri = pri->Next;
scanf("%d",&number);
/*将待处理的多项式放入链表中*/
for(int i=0;i<number;i++)
{
pre = (List)malloc(sizeof(struct Node));
scanf("%d", &pre->coefficient);
scanf("%d",&pre->exponent);
pri->Next = pre;
pre->Next = NULL;
pri=pre;
}
}
/*将两个多项式相加并放入新的链表add中*/
List AddList(List L1, List L2)
{
List P,L_1=L1,L_2=L2;
List add;//用来存放相加后的新多项式
add = CreateList();//初始化
/*将多项式相加后生成的新多项式放入add中*/
while(L_1!=NULL||L_2!=NULL)
{
if (L_1 == NULL)//当其中一个表空了,就将另外的一个表直接存入add中
{
P = L_2;
L_2=L_2->Next;
}
else if (L_2 == NULL)
{
P = L_1;
L_1=L_1->Next;
}
else if (L_1->exponent == L_2->exponent)//若两个项次数相同 ,则合并同类项,系数相加
{
P=CreateList();//用一个P来存放合并后的新项
P->coefficient= L_1->coefficient + L_2->coefficient;
P->exponent=L_1->exponent;
L_1 = L_1->Next;
L_2 = L_2->Next;
}/*项的次数更高的更先放入add*/
else if(L_1->exponent >L_2->exponent)
{
P = L_1;
L_1=L_1->Next;
}
else if(L_1->exponent <L_2->exponent)
{
P = L_2;
L_2=L_2->Next;
}
InList(add,P);//将新项放入add
}
return add;
}
/*将两项项乘生成新的多项式*/
List MultiplyList(List L1, List L2)
{
List P,P1,P2,Mult;//用P来存放相乘后的新项
Mult = CreateList();
P=CreateList();
/*把两个多项式的各项相乘分别放入新多项式中*/
/*这里不用担心新项的次数啥的,IntoList函数会完成合并同类项等动作*/
for (P1 = L1; P1 != NULL; P1 = P1->Next)
for (P2 = L2; P2 != NULL; P2 = P2->Next)
{
P->coefficient= P1->coefficient * P2->coefficient;
P->exponent=P1->exponent +P2->exponent;
InList(Mult, P);
}
return Mult;
}
/*将项接入新多项式*/
void InList(List L, List P)
{
List PL,pri;//为了不影响原来多项式,用PL来存放原本项的系数和指数
PL=CreateList();
PL->coefficient=P->coefficient;
PL->exponent=P->exponent;
/*如果该项的系数为零则无须接入*/
if(PL->coefficient==0)
return;
/*开始遍历该新多项式,为新项寻找合适的位置插入*/
pri=L;
while(pri->Next!=NULL)
{
/*在新多项式中发现指数相同的项则和合并同类项*/
if(PL->exponent==pri->Next->exponent)
{
pri->Next->coefficient+=PL->coefficient;//系数相加便可以
if(pri->Next->coefficient==0) pri->Next=pri->Next->Next;//如果合并后的新项次数为0则删除该项
return;
}
else if(PL->exponent>pri->Next->exponent)//如果发现比新项次数的项则将该项插在该项的前面
{
PL->Next=pri->Next;
pri->Next=PL;
return;
}
else
pri=pri->Next;
}
//遍历完后还没找到合适位置就将它接在链尾处
pri->Next=PL;
}
/*输出链表*/
void OutList(List L)
{
List P = L;
if (P == NULL) printf("0 0");//如果为空表则输出0 0
while (P!=NULL)
{
if(P->Next!=NULL)//最后的项后面不带空格
printf("%d %d ", P->coefficient, P->exponent);
else
printf("%d %d",P->coefficient, P->exponent);
P = P->Next;
}
}
这里最重要的就是InList()函数了,其负责处理L1和L2运算后的新项的存储和排序,它需要实现以下三个功能:
1.合并同类项
2.按降序排列多项式
3.删除系数为0的项
假如InList()函数写的好,其他的函数就会更容易实现一点。
下面单独附上InList()函数的代码:
void InList(List L, List P)
{
List PL,pri;//为了不影响原来多项式,用PL来存放原本项的系数和指数
PL=CreateList();
PL->coefficient=P->coefficient;
PL->exponent=P->exponent;
/*如果该项的系数为零则无须接入*/
if(PL->coefficient==0)
return;
/*开始遍历该新多项式,为新项寻找合适的位置插入*/
pri=L;
while(pri->Next!=NULL)
{
/*在新多项式中发现指数相同的项则和合并同类项*/
if(PL->exponent==pri->Next->exponent)
{
pri->Next->coefficient+=PL->coefficient;//系数相加便可以
if(pri->Next->coefficient==0) pri->Next=pri->Next->Next;//如果合并后的新项次数为0则删除该项
return;
}
else if(PL->exponent>pri->Next->exponent)//如果发现比新项次数的项则将该项插在该项的前面
{
PL->Next=pri->Next;
pri->Next=PL;
return;
}
else
pri=pri->Next;
}
//遍历完后还没找到合适位置就将它接在链尾处
pri->Next=PL;
}
这题要了我老命了,调试老是出错,后来着重把InList函数写了一遍,后面写起来就十分丝滑了。
看问题得要抓住问题的关键,找突破点(◕ᴗ◕✿)
还要一点点运气和亿点点努力(*❦ω❦)