设计函数分别求两个一元多项式的乘积与和。
输入分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
求和的其实课本上讲过了,就是分别遍历L1和L2,
(1)两者如果指数不等则将指数大的节点加入新链表,同时移动新链表与加入节点的指针;
(2)两者如果指数相等则系数相加,同时要判断两者是否为0,不为0时再把合并后接入新链表
(3)如果最后L1或L2有多余直接一次性接入
本题难点在于乘法
我的思路是利用之前实现的多项式加法函数,将多项式乘法转化为多项式加法
(1)用L1的每一项乘整个L2,得到一个多项式
(2)将新得到的多项式与L1前一项与整个L2相乘结果相加
如此便可以得到最终乘法结果
(1)每次遍历链表时都会忘记移动指针
(2)题目要求0多项式输出0 0 ,所以首先系数如果是0就不要加入链表,最后如果链表为空打印链表时打印 0 0
#include
#include
/*链表表示多项式的数据结构*/
typedef struct ListNode ListNode;
typedef ListNode* List;
struct ListNode {
int Coefficient, Exponent;
List Next;
};
/*实现尾插法的函数*/
void Attach(int coef, int expo, List* rear) { //传rear地址的原因是因为要在函数里修改main函数必须通过地址进行
List newNode = (List)malloc(sizeof(ListNode));
newNode->Coefficient = coef;
newNode->Exponent = expo;
(*rear)->Next = newNode;
(*rear) = (*rear)->Next;
(*rear)->Next = NULL;
}
/*用到尾插法构造链表的函数*/
List CreateList(int degree) {
List dummyHead = (List)malloc(sizeof(ListNode)); //多项式虚拟头结点
List rear = dummyHead;
rear->Next = NULL;
for(int i = 0; i < degree; i++) { //创建多项式链表
int coef, expo;
scanf("%d %d", &coef, &expo);
if(coef == 0) continue;
Attach(coef, expo, &rear);
}
return dummyHead;
}
/*打印链表*/
void PrintList(List L) {
List ptr = L->Next;
if(ptr == NULL) printf("0 0");
while(ptr) {
printf("%d %d", ptr->Coefficient, ptr->Exponent);
if(ptr->Next) printf(" ");
ptr = ptr->Next;
}
return;
}
/*删除链表*/
void DeleteList(List L) {
List ptr = L->Next;
while(ptr) {
List tmp = ptr;
ptr = ptr->Next;
free(tmp);
}
free(L);
return;
}
/*多项式加法,参数是两个链表头指针,不能操作传进来的链表*/
List AddPolynomial(List L1, List L2) {
List dummyHead = (List)malloc(sizeof(ListNode));
dummyHead->Next = NULL;
List rear = dummyHead, ptr1 = L1->Next, ptr2 = L2->Next;
while(ptr1 && ptr2) {
int expo1 = ptr1->Exponent, expo2 = ptr2->Exponent;
int coef1 = ptr1->Coefficient, coef2 = ptr2->Coefficient;
if(expo1 > expo2) {
Attach(coef1, expo1, &rear);
ptr1 = ptr1->Next;
}
else if(expo1 < expo2) {
Attach(coef2, expo2, &rear);
ptr2 = ptr2->Next;
}
else {
if((coef1 + coef2)) {
Attach(coef1 + coef2, expo1, &rear);
}
ptr1 = ptr1->Next;
ptr2 = ptr2->Next;
}
}
if(ptr1) {
while(ptr1) {
Attach(ptr1->Coefficient, ptr1->Exponent, &rear);
ptr1 = ptr1->Next;
}
}
if(ptr2) {
while(ptr2) {
Attach(ptr2->Coefficient, ptr2->Exponent, &rear);
ptr2 = ptr2->Next;
}
}
return dummyHead;
}
/*多项式乘法,参数是两个链表头指针,不能操作传进来的链表*/
List ProductPolynomial(List L1, List L2) {
List dummyHead = (List)malloc(sizeof(ListNode));
List ptr0 = dummyHead, ptr1 = L1->Next, ptr2 = L2->Next;
ptr0->Next = NULL;
while(ptr2) {
int polyCoef2 = ptr2->Coefficient, polyExpo2 = ptr2->Exponent;
List dummyHeadTmp = (List)malloc(sizeof(ListNode));
List ptrTmp = dummyHeadTmp;
ptrTmp->Next = NULL;
while(ptr1) { //将L2的每一项取出来,与L1相乘,得到一条tmp多项式链表
int polyCoef1 = ptr1->Coefficient, polyExpo1 = ptr1->Exponent;
int polyCoefTmp = polyCoef1 * polyCoef2;
int polyExpoTmp = polyExpo1 + polyExpo2;
if(polyCoefTmp == 0) continue;
Attach(polyCoefTmp, polyExpoTmp, &ptrTmp);
ptr1 = ptr1->Next;
}
dummyHead = AddPolynomial(dummyHead, dummyHeadTmp); //将这条tmp链表累加到结果链表上即可得到多项式乘法结果
DeleteList(dummyHeadTmp); //释放tmp链表
ptr1 = L1->Next; //将ptr1重新指向L1
ptr2 = ptr2->Next; //ptr2指向L2的下一项
}
return dummyHead;
}
int main() {
int degree1;
scanf("%d", °ree1);
List polynomial1 = CreateList(degree1);
int degree2;
scanf("%d", °ree2);
List polynomial2 = CreateList(degree2);
List polynomialAdd = AddPolynomial(polynomial1, polynomial2);
List polynomialPtrduct = ProductPolynomial(polynomial1, polynomial2);
PrintList(polynomialPtrduct);
printf("\n");
PrintList(polynomialAdd);
DeleteList(polynomial1);
DeleteList(polynomial2);
DeleteList(polynomialAdd);
return 0;
}