数据结构多项式运算器实验报告.docx
- 文档编号:9954447
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:20
- 大小:18.85KB
数据结构多项式运算器实验报告.docx
《数据结构多项式运算器实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构多项式运算器实验报告.docx(20页珍藏版)》请在冰豆网上搜索。
数据结构多项式运算器实验报告
多项式运算器
实验问题
本实验主要实现对多项式的创建存储、显示、复制、求和、求差、求积、n次方、n阶导、不定积分、定积分、求值、项数、销毁。
储存结构
typedefstruct{
floatcoef;
intexpn;
}term,ElemType;
typedefstructLNode{
ElemTypedata;
structLNode*next;
}*Link;
typedefstruct{
Linkhead,tail;
intlen;
}LinkList;
主要使用链表存储多项式。
算法思想
使用链表的处理方法。
程序结构
#include
#include
#include
#include
typedefstruct{
floatcoef;
intexpn;
}term,ElemType;
typedefstructLNode{
ElemTypedata;
structLNode*next;
}*Link;
typedefstruct{
Linkhead,tail;
intlen;
}LinkList;
/*====================链表-ADT====================*/
voidMakeNode(Link&p,ElemTypee){
p=(Link)malloc(sizeof(structLNode));
if(!
p)exit
(1);
p->data=e;
p->next=NULL;
}//MakeNode
voidInitList(LinkList&L){
L.head=L.tail=(Link)malloc(sizeof(LNode));
if(!
L.head)exit
(1);
L.head->next=NULL;
L.len=0;
}//InitList
voidDestroyList(LinkList&L){
Linkp,q;
p=L.head->next;
while(p){
q=p->next;
free(p);
p=q;
}
L.head->next=NULL;
L.tail=L.head;
L.len=0;
}//DestroyList
voidInsLast(LinkList&L,Links){
L.tail->next=s;
L.tail=s;
L.len++;
L.tail->next=NULL;
}//InsLast
/*====================多项式-ADT====================*/
voidCreatPolyn(LinkList&L){
terme;
Links;
scanf("%f,%d",&e.coef,&e.expn);
while(e.coef){
MakeNode(s,e);
InsLast(L,s);
scanf("%f,%d",&e.coef,&e.expn);
}
}//CreatPolyn
创建比较简单,主要调用了MakeNode()、InsLast()两个函数。
intJudge(intn){
if(n>19||n<0){
printf("存储位置选择错误!
请重新选择0-19.\n");
return1;
}
else
return0;
}//Judge
本来打算用这个函数来检查选择的存储位置是否越界,但操作起来有点困难,最后还是放弃了。
voidPrintPolyn(LinkListL){
Linkp;
p=L.head->next;
if(!
p)
printf("NULL\n");
else{
printf("y=");
if(p->data.coef>0){
if(p->data.expn==0)
printf("%f",p->data.coef);
else
printf("%fx^%d",p->data.coef,p->data.expn);
p=p->next;
}
else{
if(p->data.expn==0)
printf("%f",p->data.coef);
else
printf("%fx^%d",p->data.coef,p->data.expn);
p=p->next;
}
while(p){
if(p->data.coef>0){
if(p->data.expn==0)
printf("+%f",p->data.coef);
else
printf("+%fx^%d",p->data.coef,p->data.expn);
p=p->next;
}
else{
if(p->data.expn==0)
printf("%f",p->data.coef);
else
printf("%fx^%d",p->data.coef,p->data.expn);
if(p->next)
p=p->next;
}
}
printf("\n");
}
}//PrintPolyn
PrintPolyn()这个函数费了点事。
主要是要考虑的情况有点多,所以函数就变长了。
先考虑是否非空,还要考虑系数的正负,是否打印加号,而且第一项如果是正的不用打印加号,还要考虑是否越界。
总之就是很复杂了。
voidPrintAll(LinkListS[]){
inti;
for(i=0;i<20;i++){
printf("%d.",i);
PrintPolyn(S[i]);
}
}//PrintAll
全部打印,来查看存储状态。
还是很有用的。
voidCopyPolyn(LinkListL,LinkList&S){
terme;
Links,p;
p=L.head->next;
while(p){
e.coef=p->data.coef;
e.expn=p->data.expn;
MakeNode(s,e);
InsLast(S,s);
p=p->next;
}
S.tail->next=NULL;
}//CopyPolyn
比较简单,还是调用了MakeNode()、InsLast()两个函数,与创建差不多。
intAddPolyn(LinkList&L,LinkListP,LinkListQ){
Linka,b,c;
terme;
a=P.head->next;
b=Q.head->next;
while((a!
=NULL)&&(b!
=NULL)){
if(a->data.expn
e.coef=a->data.coef;
e.expn=a->data.expn;
MakeNode(c,e);
InsLast(L,c);
a=a->next;
}
elseif(a->data.expn>b->data.expn){
e.coef=b->data.coef;
e.expn=b->data.expn;
MakeNode(c,e);
InsLast(L,c);
b=b->next;
}
elseif((a->data.coef+b->data.coef)!
=0){
e.coef=a->data.coef+b->data.coef;
e.expn=a->data.expn;
MakeNode(c,e);
InsLast(L,c);
a=a->next;
b=b->next;
}
elseif((a->data.coef+b->data.coef)==0){
a=a->next;
b=b->next;
}
}
if(!
a&&!
b){
L.tail->next=NULL;
return0;
}
if(!
b){
while(a){
e.coef=a->data.coef;
e.expn=a->data.expn;
MakeNode(c,e);
InsLast(L,c);
a=a->next;
}
}
if(!
a){
while(b){
e.coef=b->data.coef;
e.expn=b->data.expn;
MakeNode(c,e);
InsLast(L,c);
b=b->next;
}
}
return0;
}//AddPolyn
主要是分情况讨论,a、b都非空、都空,一空。
还要考虑系数相加为零时的情况。
这个开始时没有成功,当一空一非空时运行不下去,但也检查不出错误来,放到最后,我把while里面的并列的if改成if、elseif,elseif,elseif就成功了,有点想不通。
voidSubtractPolyn(LinkList&L,LinkListP,LinkListQ){
Linkp;
p=Q.head->next;
while(p){
p->data.coef=0-p->data.coef;
p=p->next;
}
AddPolyn(L,P,Q);
p=Q.head->next;
while(p){
p->data.coef=0-p->data.coef;
p=p->next;
}
}//SubtractPolyn
有求和了求差就简单了。
先讲一个的系数变成原来的相反数,再相加,再把它变回来。
开始时忘记了p=Q.head->next,出了点错误。
doubleResultPolyn(LinkListL,floatx){
Linkp;
doubley=0;
p=L.head->next;
while(p){
y+=(pow(x,p->data.expn)*p->data.coef);
p=p->next;
}
returny;
}//ResultPolyn
这个比较简单,不多说了。
voidMultiplyPolyn(LinkList&L,LinkListP,LinkListQ){
Linkl,p,q;
LinkListE,F;
InitList(E);
InitList(F);
inti,j;
terme;
p=P.head->next;
q=Q.head->next;
for(i=0;i for(j=0;j e.coef=p->data.coef*q->data.coef; e.expn=p->data.expn+q->data.expn; MakeNode(l,e); InsLast(E,l); p=p->next; } AddPolyn(L,E,F); DestroyList(E); DestroyList(F); CopyPolyn(L,F); if(i! =Q.len-1) DestroyList(L); q=q->next; p=P.head->next; } }//MultiplyPolyn 这个我想的方法是创建两个临时的多项式,拿求积的一个多项式的项一次去乘另一个的项。 结果存在一个临时多项式E,将初始的L复制给F,然后E与F相加复制给L,L再赋值给F,销毁E、L。 不断销毁赋值最后完成。 注意最后一次不要销毁L。 voidPolyn_NFang(LinkList&L,LinkListP,intn){ inti; LinkListE; InitList(E); CopyPolyn(P,E); for(i=0;i MultiplyPolyn(L,E,P); DestroyList(E); CopyPolyn(L,E); if(i! =n-1) DestroyList(L); } }//Polyn_Nfang 这个也需要一个临时的多项式,还是不段销毁赋值。 有了求积的基础,这个就简单了。 voidPolyn_NDao(LinkList&L,LinkListP,intn){ Linkp,q; inti,j; CopyPolyn(P,L); for(i=0;i p=L.head->next; q=L.head; for(j=0;j if(p->data.expn==0){ q->next=p->next; free(p); p=q->next; L.len--; } p->data.coef=p->data.coef*p->data.expn; p->data.expn=p->data.expn-1; p=p->next; q=q->next; } } }//Polyn_Ndao 这个比较简单,就是对系数和指数的更改。 intPolyn_Ji(LinkList&L,LinkListP){ Linkp; inti; CopyPolyn(P,L); p=L.head->next; for(i=0;i if(p->data.expn==-1){ printf("对不起,本程序不能实现对-1次方的积分.请重新选择.\n"); DestroyList(L); return0; } else p=p->next; } for(i=0;i p->data.coef=p->data.coef/(p->data.expn+1); ++p->data.expn; p=p->next; } return0; }//Polyn_Ji 这个还是对系数和指数的更改,主要如果是-1次方积分出现ln(),这就麻烦了。 故此,对含-1次方的多项式不进行积分。 doublePolyn_Ding(LinkListL,floata,floatb){ doublem,n; doublee=0; LinkListP; InitList(P); Polyn_Ji(P,L); m=ResultPolyn(P,a); n=ResultPolyn(P,b); e=n-m; returne; }//Polyn_Ding 这个很简单,主要调用Polyn_Ji()和ResultPolyn()。 /*====================main====================*/ voidmain(){ intn,m,i,a,b,c; floatx,e,f; doubled; LinkListS[20]; for(i=0;i<20;i++) InitList(S[i]); printf("说明: 共有二十个多项式备用位置: 0~19。 \n菜单: \n0\t退出\n1\t创建多项式\n2\t显示多项式\n3\t复制多项式\n4\t多项式求和\n5\t多项式求差\n6\t多项式求积\n7\t多项式n次方\n8\t多项式n阶导\n9\t多项式不定积分\n10\t多项式定积分\n11\t多项式求值\n12\t多项式项数\n13\t销毁多项式\n14\t查看存储状态\n"); printf("请输入命令: "); scanf("%d",&n); while(n){ if(n>16||n<0) printf("输入命令错误! 请重新输入.\n"); switch(n){ case1: printf("1.请选择位置: "); scanf("%d",&m); while(S[m].head->next){ printf("已占用! 请重新选择存储位置: "); scanf("%d",&m); } CreatPolyn(S[m]); break; case2: printf("2.请选择位置: "); scanf("%d",&m); PrintPolyn(S[m]); break; case3: printf("3.请选择要复制的多项式的位置和复制到的位置: "); scanf("%d,%d",&a,&b); while(S[b].head->next){ printf("已占用! 请重新选择存储位置: "); scanf("%d",&b); } CopyPolyn(S[a],S[b]); break; case4: printf("4.请输入需要求和的两个多项式位置及和放置的位置: "); scanf("%d,%d,%d",&a,&b,&c); while(S[c].head->next){ printf("已占用! 请重新选择存储位置: "); scanf("%d",&c); } AddPolyn(S[c],S[a],S[b]); break; case5: printf("5.请输入需要求差的两个多项式位置及差放置的位置: "); scanf("%d,%d,%d",&a,&b,&c); while(S[c].head->next){ printf("已占用! 请重新选择存储位置: \n"); scanf("%d",&c); } SubtractPolyn(S[c],S[a],S[b]); break; case6: printf("6.请输入需要相乘的两个多项式及存储位置: "); scanf("%d,%d,%d",&a,&b,&c); if(! S[a].head->next||! S[b].head->next){ printf("多项式位置选择错误! 请重新选择.\n"); break; } while(S[c].head->next){ printf("已占用! 请重新选择存储位置: "); scanf("%d",&c); } MultiplyPolyn(S[c],S[a],S[b]); break; case7: printf("7.请输入多项式的位置,n次方及存储位置: "); scanf("%d,%d,%d",&a,&b,&c); if(! S[a].head->next){ printf("多项式位置选择错误! 请重新选择.\n"); break; } while(S[c].head->next){ printf("已占用! 请重新选择存储位置: "); scanf("%d",&c); } Polyn_NFang(S[c],S[a],b); break; case8: printf("8.请输入多项式的位置,n阶导及存储位置: "); scanf("%d,%d,%d",&a,&b,&c); if(! S[a].head->next){ printf("多项式位置选择错误! 请重新选择.\n"); break; } while(S[c].head->next){ printf("已占用! 请重新选择存储位置: "); scanf("%d",&c); } Polyn_NDao(S[c],S[a],b); break; case9: printf("请输入需要做不定积分的多项式及存储位置: "); scanf("%d,%d",&m,&n); if(! S[m].head->next){ printf("多项式位置选择错误! 请重新选择.\n"); break; } while(S[n].head->next){ printf("已占用! 请重新选择存储位置: "); scanf("%d",&n); } Polyn_Ji(S[n],S[m]); break; case10: printf("请输入需要做定积分的位置及从m积到n的值: "); scanf("%d,%f,%f",&a,&e,&f); if(! S[a].head->next){ printf("多项式位置选择错误! 请重新选择.\n"); break; } d=Polyn_Ding(S[a],e,f); printf("y=%lf\n",d); break; case11: printf("11.请输入需要求值的多项式的位置及x值: "); scanf("%d,%f",&m,&x); if(! S[m].head->next){ printf("多项式位置选择错误! 请重新选择.\n"); break; } d=ResultPolyn(S[m],x); printf("y=%lf\n",d); break; case12: printf("12.请输入多项式的位置: "); scanf("%d",&m); printf("%d号项数为%d\n",m,S[m].len); break; case13: printf("13.请输入需要销毁的多项式的位置: "); scanf("%d",&m); DestroyList(S[m]); break; case14: PrintAll(S); break; } printf("\n"); printf("说明: 共有二十个多项式备用位置: 0~19。 \n菜单: \n0\t退出\n1\t创建多项式\n2\t显示多项式\n3\t复制多项式\n4\t多项式求和\n5\t多项式求差\n6\t多项式求积\n7\t多项式n次方\n8\t多项
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 多项式 运算器 实验 报告