多项式.docx
《多项式.docx》由会员分享,可在线阅读,更多相关《多项式.docx(19页珍藏版)》请在冰豆网上搜索。
多项式
题目:
一元稀疏多项式计算器
班级:
信管09-1班姓名:
单锦芳学号:
0901050304
一、需求分析
(1)用线性链表来存储多项式的信息。
当要求输入多项式时,用户依次输入多项式的系数和指数(包括符号),其中,系数是浮点型,指数是整型,该程序会将每一项的系数和指数储存在链表的一个结点中,链表的next指针指向该多项式的下一项。
(2)演示程序是用户在键盘上输入演示程序中规定的命令从屏幕上输出显示用户输入的多项式,并显示多项式经计算以后的值。
(3)输出结果中,若系数为1,则将系数省略,若为0,将该项省略;若指数为1,指数省略,指数为0,该项为常数项。
(4)本程序的输出结果中,多项式按降幂排序。
(5)该程序实现的功能:
a:
创建多项式b:
输出多项式c:
多项式的加法运算d:
多项式的减法运算
e:
多项式的乘法运算f:
对多项式求导g:
多项式求值
二、概要设计
1、设定链表的抽象数据类型
ADTPolyn{
数据对象:
D={ai∈ElemType,i=1,2,…,m,m≥0
ElemType中的每一个元素包含一个表示系数的实数,一个表示指数的整数和一个指向下一项的指针}
数据关系:
R1={<ai-1,ai>|ai-1,ai∈D,且ai-1中的指数值<ai中的指数值,i=2,…,n}
基本操作:
CreatePolyn(&P,n)
操作结果:
输入第n项的系数和指数,建立一元多项式P
Insert(p,q)
初始条件:
一元多项式p,q已存在
操作结果:
通过插入使两多项式合并为一个,实现按降幂排序
Compare(a,b)
初始条件:
一元多项式a,b存在
操作结果:
比较a,b的指数大小
AddPolyn(pa,pb)
初始条件:
一元多项式pa,pb已经存在
操作结果:
实现两个多项式的加法
SubtractPolyn(pa,pb)
初始条件:
一元多项式pa,pb已经存在
操作结果:
实现两个多项式的减法
ValuePolyn(head,x)
操作结果:
对多项式求值
Derivative(head)
初始条件:
一元多项式head已经存在
操作结果:
对多项式求导
Derivative(pa,pb)
初始条件:
一元多项式pa,pb已经存在
操作结果:
实现两个多项式的乘法
DestroyPolyn(p)
初始条件:
一元多项式p已存在
操作结果:
将一元多项式销毁
PrintPolyn(p)
初始条件:
一元多项式p已存在
操作结果:
打印出一元多项式p
}ADTPolyn
2、本程序包含2个模块
a、主函数模块
voidmain(){
创建多项式;
选择操作;
执行运算;
输出结果;
销毁多项式;}
b、链表模块——实现链表的抽象数据类型
各模块之间的调用如下:
主函数模块
链表模块
三、详细设计
1、结点类型和部分数据定义
typedefstructLNode//存储结构定义
{
floatcoef;//系数
intexpn;//指数
structLNode*next;
}*ElemType,LNode;
2、主函数和其他函数的算法分析
voidInsert(ElemTypep,ElemTypeq);
//插入函数,将q插入到p中,用于创建多项式时,实现创建的多项式按降幂//排列
StatusCreatePolyn(ElemType&p,intn);
//实现多项式的有序创建,调用Insert函数,将各项按幂的降序排列
//n<=0,返回ERROR;n>0,返回OK
StatusDestroyPolyn(ElemTypep);
//实现多项式的销毁,销毁成功返回OK
voidPrintPolyn(ElemTypep)
//实现多项式的输出
intcompare(ElemTypea,ElemTypeb);
//比较两项指数大小,若a的指数大于b的指数,返回1;若a的指数小于
//b的指数,返回-1;若a的指数等于b的指数,返回0
ElemTypeAddPolyn(ElemTypepa,ElemTypepb);
//实现两个多项式的加法,创建一个新的多项式,依次比较pa,pb的各项指数
//调用compare函数插入到新多项式中
ElemTypeSubtractPolyn(ElemTypepa,ElemTypepb);
//实现两个多项式的减法,将pb的各项系数取相反数,然后再与pa进行加法
floatValuePolyn(ElemTypehead,intx);
//实现多项式的求值,输入一个x,逐项将其值代入,若该项指数为负,则
//除以x,将指数加1,循环,直到x为0;否则,乘以x,将指数减1,循
//环,直到x值为0
ElemTypeDerivative(ElemTypehead);
//实现多项式的求导,该项为常数项时,将该项删除,否则,将系数与指数
//相乘作系数,指数减1作指数
ElemTypeMultiplyPolyn(ElemTypepa,ElemTypepb);
//实现多项式的乘法,积的系数等于两系数相乘,积的指数等于两系数之和
//调用Insert函数
四、调试分析
1、在该程序的早期版本中,由于缺乏调试技术,源程序中没有明确对尾指针的指向,曾多次出现内存分配错误,后均通过调试改正。
这是我对调试技术有了进一步了解。
2、函数的时空分析
1)虽然该程序在输入时对输入的顺序并未作硬性要求,但create函数中附加了排序和合并同类项的功能,这样能大大减小后面的加减法的排序次数。
同时在每个函数的排序操作中,均设置了两个指针,一个指向当前结点,另一个指向他的前继结点,这样能方便地在两个指针之间进行插入操作。
create函数中的时间复杂度最大为O((n-1)*n/2),Insert1、Insert2函数中的时间复杂度最大为O(m+n)(其中,p为n项,q为m项,插入操作是将q插入p中)。
2)在create函数中,插入操作中除新开辟的头节点和第一个结点外,其他皆为原链表中的结点,因此空间复杂度为O(8*(m+2)),Insert1、Insert2函数中的空间复杂度最大为O(8*(m+n))(其中,p为n项,q为m项,插入操作是将q插入p中)。
3、在求解合并后多项式项数中,该程序引用了一个全局变量,使项数的求解变得很简单,不需用一个函数来实现。
4、本次程序采用抽象数据类型来实现,使每一个模块的功能变得非常清晰,且模块之间的调用关系也非常明朗。
这样的程序设计方法使编程者的思路非常清晰,同时便于对各个模块进行单独调试,非常方便。
通过本次试验作业,我确实得到了一次良好的程序设计训练。
五、用户手册
1、本程序的运行环境为DOS操作系统,执行文件为:
一元稀疏多项式.exe。
2、进入演示程序后即显示文本方式的用户界面:
3、看到“请选择您要进行的操作(1~8):
”提示后,依次输入一项的系数和指数,按回车键结束。
4、接受其他命令后即执行相应运算和显示相应结果,在此不再一一演示。
六、测试结果
测试数据1:
多项式1:
2,15,8-3.1,11
多项式2:
7,0-5,811,9
运算方式:
加法
结果:
测试数据2:
多项式1:
:
6,-3-1,14.4,2-1.2,9
多项式2:
-6,-35.4,2-1,27.8,15
运算方式:
减法
结果:
附录
源程序:
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineOVERFLOW-1
typedefstructLNode//存储结构定义
{
floatcoef;//系数
intexpn;//指数
structLNode*next;
}*ElemType,LNode;
typedefintStatus;
//typedeftermElemType;
voidInsert(ElemTypep,ElemTypeq)//插入函数,将各项按幂的降序排列
{
if(p->coef==0)//若系数为0释放结点
free(p);
else
{
ElemTypes1,s2;
s1=q;
s2=q->next;
while(s2&&p->expnexpn)//查找插入位置
{
s1=s2;
s2=s2->next;
}
if(s2&&p->expn==s2->expn)//若系数相同,则把它们的系数相加
{
s2->coef+=p->coef;
free(p);
if(!
s2->coef)//若相加后系数为0,则释放结点
{
s1->next=s2->next;
free(s2);
}
}
else//若为新指数项则插入结点
{
p->next=s2;
s1->next=p;
}
}
}
StatusCreatePolyn(ElemType&p,intn)//实现多项式的有序创建,将各项按幂的降序排列
{
if(n<=0)
returnERROR;
else
{
inti;
ElemTypeq;
q=p=(ElemType)malloc(sizeof(LNode));
p->next=NULL;
for(i=0;i{
q=(ElemType)malloc(sizeof(LNode));//建立新结点
printf("请输入第%d项的系数与指数:
",i+1);
scanf("%f%d",&q->coef,&q->expn);
Insert(q,p);//调用Insert函数
}
returnOK;
}
}
StatusDestroyPolyn(ElemTypep)//实现多项式的销毁
{
ElemTypeq1,q2;
q1=p->next;
q2=q1->next;
while(q1->next)
{
free(q1);
q1=q2;
q2=q2->next;
}
returnOK;
}
voidPrintPolyn(ElemTypep)//实现多项式的输出
{
ElemTypeq=p->next;
intcount=1;//项数计数器
if(!
q)//多项式为空
printf("该多项式为空!
\n");
while(q)
{
if(q->coef>0&&count!
=1)//若该项的系数不为0且不是第一项
printf("+");
if(q->coef!
=1&&q->coef!
=-1)//若该项的系数不为正负1
{
printf("%f",q->coef);
if(q->expn==1)//若指数为1输出X
printf("x");
elseif(q->expn)//若指数不为0
printf("x^%d",q->expn);
}
else
{
if(q->coef==1)
{
if(!
q->expn)//若系数为1,指数为0
printf("1");
elseif(q->expn==1)//若系数为1,指数也为1
printf("x");
else
printf("x^%d",q->expn);
}
if(q->coef==-1)
{
if(!
q->expn)//若系数为-1,指数为0
printf("-1");
elseif(q->expn==1)//若系数为-1,指数为1
printf("-x");
else
printf("-x^%d",q->expn);
}
}
q=q->next;
count++;
}
printf("\n");
}
intcompare(ElemTypea,ElemTypeb)//比较指数大小
{
if(a&&b)
{
if(a->expn>b->expn)//a,b均不为空时,a的指数大于b的指数返回1
return1;
elseif(a->expnexpn)
return-1;
else
return0;
}
elseif(!
a&&b)//a为空b不为空时返回-1
return-1;
else//b为空a不为空时返回1
return1;
}
ElemTypeAddPolyn(ElemTypepa,ElemTypepb)//实现两个多项式的加法,和按幂的降序排列
{
ElemTypeqa=pa->next;
ElemTypeqb=pb->next;
ElemTypeheadc,hc,qc;
hc=(ElemType)malloc(sizeof(LNode));//建立头结点
hc->next=NULL;
headc=hc;
//headc=(ElemType)malloc(sizeof(LNode));
while(qa||qb)
{
qc=(ElemType)malloc(sizeof(LNode));
switch(compare(qa,qb))//按幂降序将各项插入到qc中
{
case1:
{
qc->coef=qa->coef;
qc->expn=qa->expn;
qa=qa->next;
break;
}
case0:
{
qc->coef=qa->coef+qb->coef;
qc->expn=qa->expn;
qa=qa->next;
qb=qb->next;
break;
}
case-1:
{
qc->coef=qb->coef;
qc->coef=qb->coef;
qb=qb->next;
break;
}
}
if(qc->coef!
=0)//若该项系数不为0,则放到hc中
{
qc->next=hc->next;
hc->next=qc;
hc=qc;
}
else//否则释放结点
free(qc);
}
returnheadc;
}
ElemTypeSubtractPolyn(ElemTypepa,ElemTypepb)//实现多项式的减法
{
ElemTypeh=pb;
ElemTypep=pb->next;
ElemTypepd;
//pd=(ElemType)malloc(sizeof(LNode));
while(p)//将pb的各项系数取相反数
{
p->coef*=-1;
p=p->next;
}
pd=AddPolyn(pa,h);//调用加法
for(p=h->next;p;p=p->next)//将pb还原
p->coef*=-1;
returnpd;
}
floatValuePolyn(ElemTypehead,intx)//实现多项式的求值
{
ElemTypep;
inti;
floatsum=0,t;
for(p=head->next;p;p=p->next)
{
t=1;
for(i=p->expn;i!
=0;)
{
if(i<0)//若指数为负,则除以x,直到指数为0
{
t/=x;
i++;
}
else//若指数为非负,则乘以x,直到指数为0
{
t*=x;
i--;
}
}
sum+=p->coef*t;//最后每项乘以系数,求和
}
returnsum;
}
ElemTypeDerivative(ElemTypehead)//实现多项式的求导
{
ElemTypeq=head->next,p1,p2,hd;
hd=p1=(ElemType)malloc(sizeof(LNode));//建立头结点
hd->next=NULL;
while(q)
{
if(q->expn!
=0)//该项不是常数项时
{
p2=(ElemType)malloc(sizeof(LNode));
p2->coef=q->coef*q->expn;
p2->expn=q->expn-1;
p2->next=p1->next;//连接结点
p1->next=p2;
//p1=p2;
}
q=q->next;
}
returnhd;
}
ElemTypeMultiplyPolyn(ElemTypepa,ElemTypepb)//实现多项式乘法
{
ElemTypehf,pf;
ElemTypeqa=pa->next;
ElemTypeqb=pb->next;
hf=(ElemType)malloc(sizeof(LNode));
hf->next=NULL;
for(;qa;qa=qa->next)
for(qb=qb->next;qb;qb=qb->next)
{
pf=(ElemType)malloc(sizeof(LNode));
pf->coef=qa->coef*qb->coef;//积的系数等于两系数相乘
pf->expn=qa->expn+qb->expn;//积的指数等于两指数之和
Insert(pf,hf);//调用Insert函数
}
returnhf;
}
voidmain()
{
//inta;
//intm,n,x;
/*pa=(ElemType)malloc(sizeof(structPolynomial));
pb=(ElemType)malloc(sizeof(structPolynomial));
pc=(ElemType)malloc(sizeof(structPolynomial));
pd=(ElemType)malloc(sizeof(structPolynomial));*/
charselect;
ElemTypepa,pb,pc,pd;
printf("***********************************************************\n");
printf("**一元稀疏多项式运算器**\n\n");
printf("menu:
\n1:
创建多项式\n2:
输出多项式\n3:
多项式的加法运算\n4:
多项式的减法运算\n5:
多项式的乘法运算\n6:
对多项式求导\n7:
代入x求多项式的值\n8:
退出程序\n");
printf("***********************************************************\n");
while
(1)
{
printf("请选择您要进行的操作(1~8):
\n");
scanf("%c",&select);
switch(select)
{
case'1':
{
intm;
printf("请输入多项式的项数:
");
scanf("%d",&m);
CreatePolyn(pa,m);
printf("多项式创建成功!
\n");
break;
/*printf("请输入b的项数:
");
scanf("%d",&n);
pb=CreatePolyn(pb,n);
printf("是否继续操作(Y\N)?
\n");
scanf("%c",ch);
if(ch=='N'||'n')
break;*/
//break;
}
case'2':
{
printf("\n多项式a=");
PrintPolyn(pa);
break;
}
case'3':
{
intm,n;
printf("请输入a的项数:
");
scanf("%d",&m);
CreatePolyn(pa,m);
printf("\n多项式a=");
PrintPolyn(pa);
printf("请输入b的项数:
");
scanf("%d",&n);
CreatePolyn(pb,n);
printf("\n多项式b=");
PrintPolyn(pb);
pc=AddPolyn(pa,pb);
printf("\na+b=");
PrintPolyn(pc);
break;
}
case'4':
{
intm,n;
printf("请输入a的项数:
");
scanf("%d",&m);
CreatePolyn(pa,m);
printf("\n多项式a=");
PrintPolyn(pa);
printf("请输入b的项数:
");
scanf("%d",&n);
CreatePolyn(pb,n);
printf("\n多项式b=");
PrintPolyn(pb);
pc=SubtractPolyn(pa,pb);
printf("\na-b=");
PrintPolyn(pc);
break;
}
case'5':
{
pc=MultiplyPolyn(pa,pb);
printf("\na*b=");
PrintPolyn(pc);
break;
}
case'6':
{
pc=Derivative(pa);
printf("\n多项式a