没啥好说的,逐项加逐项乘即可。
另外写了一个算幂的函数,动不动爆int。
#include <stdio.h>
#include <stdlib.h>
#define MAX_FORMULA_LENGTH 100
struct PolyNode
{
int coef;
int expon;
struct PolyNode* next;
};
typedef struct PolyNode* Polynomial;
Polynomial readInPolynomial();
//读入多项式,格式为:项数 系数1 指数1 系数2 指数2...
//返回不带头结点的链表
void printPolynomial(Polynomial p);
//格式化输出多项式,符合书写习惯
Polynomial addTwoPolynomial(Polynomial p1,Polynomial p2);
//两多项式相加,返回新的多项式
int compareExpon(Polynomial p1,Polynomial p2);
//比较两个节点的指数大小,注意节点也可以看做只有一项的多项式
Polynomial createNode(int coef,int expon);
//创建系数为coef指数为expon的节点
void patchNode(int coef,int expon,Polynomial* pRear);
//向pRear后追加系数为coef,指数为expon的节点
Polynomial polynomialMultiply(Polynomial p1,Polynomial p2);
//两多项式相乘,返回新的多项式
void printBarePolynomial(Polynomial p);
//仅输出系数和指数
Polynomial polynomialPower(Polynomial base,int expon);
//计算多项式base的expon次幂
Polynomial readInPolynomial()
{
int coef,expon,len;
Polynomial rFront=NULL,rRear=NULL,rCurrent=NULL;
//resultFront和resultRear表示最后结果的头指针和尾指针
scanf("%d",&len);
while(len--)
{
scanf("%d%d",&coef,&expon);
rCurrent=createNode(coef,expon);
if(!rFront)
rFront=rRear=rCurrent;
else
{
rRear->next=rCurrent;
rRear=rCurrent;
}
}
return rFront;
}
void printPolynomial(Polynomial p)
{
if(!p) printf("0 0");
while(p)
{
switch(p->coef)
{
case 1:break;//系数为1不写
case -1:putchar('-');break;//系数为-1只写符号
default:printf("%d",p->coef );
}
if(p->expon!=0)//指数为0时,不打x^0,直接写coef
{
putchar('x');
if(p->expon!=1)//指数为1时,不打^1,但是x要写
printf("^%d",p->expon );
}
if(p->next && p->next->coef>0) putchar('+');
p=p->next;
}
putchar('\n');
}
void printBarePolynomial(Polynomial p)
{
if(!p) printf("0 0");
for(;p;p=p->next)
{
printf("%d %d",p->coef,p->expon);
if(p->next) putchar(' ');//这里是必要的,最后一个空格一打就格式错误
}
putchar('\n');
}
Polynomial addTwoPolynomial(Polynomial p1,Polynomial p2)
{
Polynomial rFront,rRear;
rFront=(Polynomial)malloc(sizeof(struct PolyNode));
rFront->next=NULL;
rRear=rFront;
//先创建一个哨兵头结点方便patch,最后再删掉
while(p1&&p2)
{
switch(compareExpon(p1,p2))
{
case 1://说明p1的指数大,直接把p1接到r上
patchNode(p1->coef,p1->expon,&rRear);
p1=p1->next;
break;
case 0://说明p1和p2的指数一样,系数相加,如果不为零就加到后面
if(p1->coef + p2->coef !=0)
patchNode(p1->coef+p2->coef,p1->expon,&rRear);
p1=p1->next;
p2=p2->next;
break;
case -1:
patchNode(p2->coef,p2->expon,&rRear);
p2=p2->next;
break;
}
}
//最后肯定有一个多项式的迭代器变成NULL了
for(;p1;p1=p1->next) patchNode(p1->coef,p1->expon,&rRear);
for(;p2;p2=p2->next) patchNode(p2->coef,p2->expon,&rRear);
rRear->next=NULL;//封尾
Polynomial tmp=rFront;
rFront=rFront->next;//准备删除哨兵,如果链表中没有元素,rFront也应该是NULL
free(tmp);
return rFront;
}
int compareExpon(Polynomial p1,Polynomial p2)
{
if(p1->expon > p2->expon)
return 1;
else if(p1->expon == p2->expon)
return 0;
else return -1;
}
Polynomial createNode(int coef,int expon)
{
Polynomial c=(Polynomial)malloc(sizeof(struct PolyNode));
c->coef=coef;
c->expon=expon;
c->next=NULL;
return c;
}
void patchNode(int coef,int expon,Polynomial* pRear)
//同时增加节点和后移rear
//注意pRear是rear指针的指针
{
if(coef==0 && expon==0 ) return ;//系数指数都为零,没必要加上去
Polynomial c=createNode(coef,expon);
(*pRear)->next=c;
*pRear=c;
}
Polynomial polynomialMultiply(Polynomial p1,Polynomial p2)
{
Polynomial result=NULL,lastResult,tmp;
//创建哨兵头结点
Polynomial p2_ori=p2;
for(;p1;p1=p1->next)
{
for(p2=p2_ori;p2;p2=p2->next)
{
lastResult=result;
tmp=createNode((p1->coef)*(p2->coef),(p1->expon)+(p2->expon));
result=addTwoPolynomial(result,tmp);//注意返回的是一个新的多项式链表,之前的要放掉
free(lastResult);
}
}
//逐项相乘,再与原来的相加
//addTwoPolynomial会执行同类项的合并
return result;
}
Polynomial polynomialPower(Polynomial base,int expon)
{
Polynomial result=createNode(1,0);
while(expon--)
result=polynomialMultiply(result,base);
return result;
}
int main(int argc, char const *argv[])
{
Polynomial p1,p2;
p1=readInPolynomial();
p2=readInPolynomial();
printBarePolynomial(polynomialMultiply(p1,p2));
printBarePolynomial(addTwoPolynomial(p1,p2));
return 0;
}
设计函数分别求两个一元多项式的乘积与和。
输入格式:
输入分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