一、基本概念
设 a0,a1,…,an都是数域 F 中的数, n 是非负整数,那么表达式anxn +an-1xn-1+…+a2x2 +a1x1+ a0x0(an≠0) 叫做数域 F上一个文字 x 的多项式或一元多项式。
在多项式中,a0叫做零次多项式或常数项,a1x 叫做一次项,一般,aix 叫做i次项,ai 叫做 i 次项的系数。一元多项式用符号 f(x),g(x),…来表示。
一元稀疏多项式: 在一元多项式中,若系数为0的项数目(也就是不存在的项,指的是比最高次低的项)远远多于非0项的数目(存在的项),并且非0项分布没有规律时,则称该一元多项式为一元稀疏多项式。
二、问题描述
- 输出多项式,输出形式为整数序列:n,a1,e1,a2,e2,…,an,en,其中n是多项式的项数,ai,ei分别是第i 项的系数和指数,序列按指数降序排列。
- 实现多项式a和b相加。
- 实现多项式a和b相减。
- 实现多项式a和b相乘。
输入举例:
7-5x2+9x5— >3 7 0 -5 2 9 5
测试用例:
(x + x2) + 0 = x + x2
(x + x2) - (x + x2) = 0
0 + 0 = 0
(x + x2) + (-x + 5x5) = x2 + 5x5
三、多项式存储
一元稀疏多项式用链表存储效率较高。
typedef struct Polynomial{//项
float coef;//系数
int expn;//指数
struct Polynomial *next;//指针,下一个项
}Polynomial;
程序中的链表,都是带有头结点的,可以方便链表的操作。
以多项式x + x2的存储为例。如下图:
一元稀疏多项式链表构建代码:
void createPolynomial(Polynomial *head){
printf("请输入项数:");
int n;
scanf("%d",&n);//获取项数
for(int i=1;i<=n;i++){
Polynomial *p = (Polynomial *)malloc(sizeof(Polynomial));
printf("请输入第%d项的系数和指数:",i);
scanf("%f %d",&p->coef,&p->expn);
if(p->coef == 0)//系数为0,不存储
free(p);
else{
Polynomial *p1, *p2;//两个指针一前一后便于操作
p1 = head;
p2 = head->next;
while(p2 != NULL && p2->expn < p->expn){//找到指数大于p的 / 或者为空
p1 = p2;
p2 = p2->next;
}
if(p2 != NULL && p2->expn == p->expn){//指数相等,合并
p2->coef += p->coef;
if(p2->coef == 0){//若合并后系数为0,则删除该项
p1->next = p2->next;
free(p2);
}
free(p);
}
else{//不存在指数相等,则添加在p1后面
p->next = p2;
p1->next = p;
}
}
}
}
四、多项式加减法
基本思路:所有的多项式的是进行指数排序的,所以我们可以像单调链表的合并一样操作。
- 当指数相等时,系数相加(减法时则相减);相加完的系数若不为0,则存进链表C;
- 若指数不相等,若A的指数小于B的,将A的节点里的系数,指数都存进链表C;
- 反之,则将B的节点里的系数,指数都存进链表C;
- 当有一个链表的后几项多出来时,也将其存进链表C。
多项式加减法的代码实现:index控制加减,1为加,-1为减;A+B或A-B;返回结果链表
Polynomial* addPolynomial(Polynomial *headA, Polynomial *headB,int index){//headA:多项式A;headB:多项式B;index:加减法标记,加法1,减法-1
Polynomial *headC = (Polynomial *)malloc(sizeof(Polynomial));//创建多项式c
headC->next = NULL;
Polynomial *a1 = headA, *a2 = headA->next;//多项式A设置两个标记
Polynomial *b1 = headB, *b2 = headB->next;//多项式B设置两个标记
Polynomial *c1 = headC;//多项式C的尾部标记
while(a2 && b2){//循环比较,指数小的放前面
if(a2->expn < b2->expn){//a2的指数小于b2,则将a2放入c的尾
a1->next = a2->next;//将a2从a中分离出来
a2->next = c1->next;
c1->next = a2;//将a2接在c的尾
a2 = a1->next;//a2指向a1的后一个结点
c1 = c1->next;//c1移动到c的尾(由于刚刚添加了一个,所以往后移一个)
}
else if(a2->expn == b2->expn){//a2和b2指数相同,两者合并,在放入c的尾
a2->coef += index * b2->coef;//系数和,设置index可以控制加减法
if(a2->coef != 0){//合并后系数不为0,需要将合并后的a2加入c
a1->next = a2->next;//将a2从a中分离出来
a2->next = c1->next;
c1->next = a2;//将a2接在c的尾
c1 = c1->next;//c1移动到c的尾(由于刚刚添加了一个,所以往后移一个)
a2 = a1->next;//a2指向a1的后一个节点
b1->next = b2->next;//将b2也分离出来
free(b2);//释放b2的空间
b2 = b1->next;//b2指向b1的后一个节点
}
else{//合并后系数为0,则不需要加入到c中
a1->next = a2->next;//将a2去除
free(a2);//释放a2空间
a2 = a1->next;
b1->next = b2->next;//将b2去除
free(b2);//释放b2空间
b2 = b1->next;
}
}
else{//b2的指数小于a2,则将b2放入c的尾
b1->next = b2->next;//将b2从b中分离出来
b2->next = c1->next;
c1->next = b2;//将b2接在c的尾
b2 = b1->next;//b2指向b1的下一个节点
c1 = c1->next;//c1移动到c的尾(由于刚刚添加了一个,所以往后移一个)
}
}
while(a2){
a2->coef *= index;//减,就让系数变号
a1->next = a2->next;//将a2接在c后面
a2->next = c1->next;
c1->next = a2;
c1 = c1->next;
a2 = a1->next;
}
while(b2){
b2->coef *= index;//减,就让系数变号
b1->next = b2->next;//将b2接在c后面
b2->next = c1->next;
c1->next = b2;
c1 = c1->next;
b2 = b1->next;
}
return headC;//返回多项式c
}
五、多项式相乘
基本思路:按位相乘,循环遍历;时间复杂度n2;
A = a1xi1+a2xi2
B = b1xi3+b2xi4
A * B = a1*b1xi1+i3 + a1*b2xi1+i4 + a2*b1xi2+i3 + a2*b2xi2+i4
Polynomial* multiplyPolynomial(Polynomial *headA, Polynomial *headB){//A乘B
Polynomial *headC = (Polynomial *)malloc(sizeof(Polynomial));//创建多项式c
headC->next = NULL;
Polynomial *a1 = headA, *a2 = headA->next;//多项式A设置两个标记
Polynomial *b1 = headB, *b2 = headB->next;//多项式B设置两个标记
Polynomial *c1 = headC;//多项式C的尾部标记
while(a2){
b2 = headB->next;
while(b2){
Polynomial *p = (Polynomial *)malloc(sizeof(Polynomial));
p->coef = a2->coef * b2->coef;//系数相差
p->expn = a2->expn + b2->expn;//指数相加
if(p->coef == 0)//系数为0,不存储
free(p);
else{
Polynomial *p1, *p2;//两个指针一前一后便于操作
p1 = c1;
p2 = c1->next;
while(p2 != NULL && p2->expn < p->expn){//找到指数大于p的 / 或者为空
p1 = p2;
p2 = p2->next;
}
if(p2 != NULL && p2->expn == p->expn){//指数相等,合并
p2->coef += p->coef;
if(p2->coef == 0){//若合并后系数为0,则删除该项
p1->next = p2->next;
free(p2);
}
free(p);
}
else{//不存在指数相等,则添加在p1后面
p->next = p2;
p1->next = p;
}
}
b2 = b2->next;//b2向下移一个
}
a2 = a2->next;//a2向下移一个
}
return headC;//返回多项式c
}