#include <stdio.h>
#include <stdlib.h>
typedef struct PolyNode *Polynomial;//存储结构为:带头节点的单链表
struct PolyNode {
int coef;//多项式系数
int expon;//多项式指数
Polynomial next;//指向下一个节点
};
typedef Polynomial PList;
typedef struct array{//建立一个线性表,用来作为中转将单链表逆序
int *data;//存单链表中多项式的数据,下标表示多项式的指数
int size;//线性表的大小
int length;//线性表的长度
}Array;
PList PolyRead();//读入一个多项式
Array CreatArray();//初始化一个线性表
PList IncreasingPower(PList p);//将一个降幂的多项式升幂排序
PList Add(PList p1,PList p2);//两个多项式相加
PList Sub(PList p1,PList p2);//两个多项式相减
PList Mult(PList p1,PList p2);//两个多项式相乘
void PrintPoly(PList p);//输出多项式
void FreeLink(PList p);//清空链表
PList MultTool(PList p1,PList p2);//乘法所需用到的一个工具,用来实现一个多项式中的某一项与另一个多项式做乘法运算
int main()
{
printf("欢迎来到一元多项式计算器\n");
printf("请输入您要进行的操作(如+、-、*):\n");
char ope;
scanf("%c",&ope);//输入操作符(如+、-、*)
PList p1,p2,pap,psp,pmp;
p1=PolyRead();//创建第一个多项式
p2=PolyRead();//创建第二个多项式
switch (ope){
case '+':
printf("两个多项式相加的结果是:\n");
pap=Add(p1,p2);
printf("降幂:");
PrintPoly(pap);
pap=IncreasingPower(pap);//将一个降幂的多项式升幂排序
printf("升幂:");
PrintPoly(pap);
break;
case '-':
printf("两个多项式相减的结果是:\n");
psp=Sub(p1,p2);
printf("降幂:");
PrintPoly(psp);
psp=IncreasingPower(psp);//将一个降幂的多项式升幂排序
printf("升幂:");
PrintPoly(psp);
break;
case '*':
printf("两个多项式相乘的结果是:\n");
pmp=Mult(p1,p2);
printf("降幂:");
PrintPoly(pmp);
pmp=IncreasingPower(pmp);//将一个降幂的多项式升幂排序
printf("升幂:");
PrintPoly(pmp);
break;
default :
printf("输入错误,请重新输入。\n注意:只能输入+、-、*\n");
}
return 0;
}
PList PolyRead(){
PList p,r,t;
p=(PList)malloc(sizeof(struct PolyNode));
r=p;
int c,e;
printf("只需按降幂的顺序输入多项式的系数和指数即可\n");
printf("若要结束输入,请回车后按“Ctrl+Z”键,再次回车即可结束\n");
while(scanf("%d%d",&c,&e)!=EOF){
t=(PList)malloc(sizeof(struct PolyNode));
t->coef=c;
t->expon=e;
r->next=t;
r=t;
}
r->next=NULL;
return p;
}
Array CreatArray(){
Array arr;
arr.size=220;
arr.length=0;
arr.data=(int *)malloc(sizeof(int)*arr.size);
//将线性表中的元素初始化为0
for(int i=0;i<arr.size;i++) arr.data[i]=0;
return arr;
}
PList IncreasingPower(PList p){
Array arr=CreatArray();
PList pi=(PList)malloc(sizeof(struct PolyNode));
PList t=p->next,r=pi,s;
//将单链表中的元素转移到线性表中
while(t){
arr.data[t->expon]=t->coef;
if(arr.length < t->expon) arr.length=t->expon;
t=t->next;
}
FreeLink(p);//释放存储降幂排序多项式的单链表
arr.length++;
//利用线性表的有序性,将已经升幂排好序的多项式重新转到线性表中
for(int i=0;i<arr.length;++i){
if(arr.data[i]==0) continue;
s=(PList)malloc(sizeof(struct PolyNode));
s->expon=i;
s->coef=arr.data[i];
r->next=s;
r=s;
}
r->next=NULL;
free(arr.data);//释放线性表中的元素所占用的空间
return pi;
}
PList Mult(PList p1,PList p2){
PList t1=p1->next,t2=p2->next,pp,t;
pp=(PList)malloc(sizeof(struct PolyNode));
pp->next=NULL;
while(t1){
t=MultTool(t1,t2);//将t1中的每一项乘以t2中的所有项,存储到t中
pp=Add(t,pp);//将t加到pp中
FreeLink(t);//释放t
t1=t1->next;
}
return pp;
}
PList Add(PList p1,PList p2){
PList t1=p1->next,t2=p2->next,ps,r,t;
ps=(PList)malloc(sizeof(struct PolyNode));
r=ps;
//t1和t2都不为空时,通过比较,合并到单链表中
while(t1 && t2){
t=(PList)malloc(sizeof(struct PolyNode));
if(t1->expon > t2->expon){
t->coef=t1->coef;
t->expon=t1->expon;
r->next=t;
r=t;
t1=t1->next;
}else if(t1->expon < t2->expon){
t->coef=t2->coef;
t->expon=t2->expon;
r->next=t;
r=t;
t2=t2->next;
}else{
int sum=t1->coef+t2->coef;
//当合并同类项不为0时,存入单链表中
if(sum){
t->coef=sum;
t->expon=t1->expon;
r->next=t;
r=t;
}
t1=t1->next;
t2=t2->next;
}
}
//当t2为空时,将t1中剩下的元素放到单链表中
while(t1){
t=(PList)malloc(sizeof(struct PolyNode));
t->coef=t1->coef;
t->expon=t1->expon;
r->next=t;
r=t;
t1=t1->next;
}
//当t1为空时,将t2中剩下的元素放到单链表中
while(t2){
t=(PList)malloc(sizeof(struct PolyNode));
t->coef=t2->coef;
t->expon=t2->expon;
r->next=t;
r=t;
t2=t2->next;
}
r->next=NULL;
return ps;
}
PList Sub(PList p1,PList p2){
PList trans=p2->next,ps;
//将t2中的系数求反
while(trans){
trans->coef=0-trans->coef;
trans=trans->next;
}
ps=Add(p1,p2);
return ps;
}
void PrintPoly(PList p){
PList t=p->next;
if(!t){
printf("0 0");//零多项式输出0 0
} else {
while(t){
//只有项的系数不为0时才能输出
if(t->coef != 0){
//当指数为0时,只输出系数
if(t->expon==0) printf("%d",t->coef);
//系数和指数都为1,输出x
else if(t->coef == 1 && t->expon == 1) printf("x");
//系数为-1,指数为1,输出-x
else if(t->coef == -1 && t->expon == 1) printf("-x");
//系数为1,指数不为1,不输出系数
else if(t->coef == 1 && t->expon != 1) printf("x^%d",t->expon);
//系数为-1,但是指数不为1,系数只输出-
else if(t->coef == -1 && t->expon != 1) printf("-x^%d",t->expon);
//系数不是1或-1,指数为1,不输出指数
else if((t->coef != 1 || t->coef != -1) && t->expon == 1) printf("%dx",t->coef);
//系数不是1或-1,指数不为1,系数和指数都输出
else if((t->coef != 1 || t->coef != -1) && t->expon != 1) printf("%dx^%d",t->coef,t->expon);
//如果有下一项且下一项的系数为大于0的数,则输出+
if(t->next && t->next->coef>0) printf("+");
t=t->next;
}
}
}
printf("\n");
}
void FreeLink(PList p){
PList r=p->next,s;
while(r){
s=r->next;
free(r);
r=s;
}
free(p);
}
PList MultTool(PList p1,PList p2){
PList t1=p1,t2=p2,t,r,temp;
t=(PList)malloc(sizeof(struct PolyNode));
r=t;
while(t2){
temp=(PList)malloc(sizeof(struct PolyNode));
temp->coef=t1->coef*t2->coef;
temp->expon=t1->expon+t2->expon;
r->next=temp;
r=temp;
t2=t2->next;
}
r->next=NULL;
return t;
}
在设计一元多项式计算器时,考虑到多项式可能较为稀疏,所以采用单链表的存储方式。
在设计中遇到的困难:如何将两个多项式相乘、如何将降幂的多项式转换为升幂顺序的多项式并输出。
解决方案:对于多项式相乘,利用一个工具函数,将多项式的某一项与另一个多项式的每一项相乘并返回,将返回的多项式相加便可得到结果;对于逆序输出,利用一个线性表,将单链表中的元素存到一个线性表中,多项式的指数为线性表的下标,因此存入时,便已经按升幂的顺序排好了,只需将线性表中的元素再次存回单链表即可得到升幂的结果。
本文介绍了一种使用单链表存储稀疏一元多项式的方法,并详细阐述了解决多项式相乘及从降幂转为升幂输出的技术方案。通过工具函数实现多项式相乘,利用线性表辅助完成升幂排序。

8344

被折叠的 条评论
为什么被折叠?



