题目一元多项式的加法减法乘法的实现.docx
《题目一元多项式的加法减法乘法的实现.docx》由会员分享,可在线阅读,更多相关《题目一元多项式的加法减法乘法的实现.docx(52页珍藏版)》请在冰豆网上搜索。
题目一元多项式的加法减法乘法的实现
理学院
课程设计说明书
课程名称:
数据结构与算法A设计实践
课程代码:
6015059
题目一:
一元多项式加法、减法、乘法
年级/专业/班:
2013/信科/2班
学生姓名:
冯金慧
学 号:
3120130902209
开始时间:
2015年12月28日
完成时间:
2016年01月10日
课程设计成绩:
学习态度及平时成绩(30)
技术水平与实际能力(20)
创新(5)
说明书撰写质量(45)
总分(100)
指导教师签名:
年月日
数据结构与算法A设计实践任务书
学院名称:
理学院课程代码:
_6015059________
专业:
信科年级:
2012
一、设计题目
一元多项式的加法、减法、乘法的实现(限最多1人完成)
二、主要内容
完成一无多项式的基本运算功能。
三、具体要求及提交的材料
设有一元多项式Am(x)和Bn(x).
Am(x)=A0+A1x1+A2x2+A3x3+…+Amxm
Bn(x)=B0+B1x1+B2x2+B3x3+…+Bnxn
请实现求M(x)=Am(x)+Bn(x)、M(x)=Am(x)-Bn(x)和M(x)=Am(x)×Bn(x)。
要求:
1)首先判定多项式是否稀疏
2)分别采用顺序和动态存储结构实现;
3)结果M(x)中无重复阶项和无零系数项;
要求输出结果的升幂和降幂两种排列情况
测试数据及测试结果请在上交的资料中写明;必须上机调试通过
按《数据结构课程设计大纲》中的要求完成课程设计报告格式。
设计结束后,每个学生必须上交的材料有:
1《课程设计报告》打印稿一份2.课程设计的源代码电子文档一份
四、主要技术路线提示
稀疏的多项式最好采用链式存储结构;两式相减与相加的算法是一致的,只是减式的数据项反号;两式相乘是两式相加的变形。
五、进度安排
共计两周时间,建议进度安排如下:
1.选题,应该在上机实验之前完成2.需求分析、概要设计可分配4学时完成
2.详细设计可分配4学时4.调试和分析可分配10学时。
2学时的机动,可提前安排部分提前结束任务的学生答辩
六、推荐参考资料
1.冯博琴等编著,《软件技术基础》(修改版),西安交通大学出版社,1997
2.严蔚敏等著,《数据结构》,清华大学出版社,2003
3.李芸芳等著,《软件技术基础》(第二版),清华大学出版社,2000
4.徐孝凯等著,《数据结构(C语言描述)》,清华大学出版社,2004
指导教师签名日期年月日
系主任审核日期年月日
摘要
一元多项式计算是用C语言设计一个一元多项式简单计算机,它能够实现按指数降幂排列或者按指数升幂排列建立并输出多项式,并且能够完一元多项式的四则运算,并将其运算结果输出的功能。
一元多项式的存储方式分为静态数组存储和动态链表存储两种方式,两种方式的特点各不相同,顺序存储简单明了,但是缺乏灵活性,当多项式为稀疏多项式时,顺序存储则会浪费许多存储空间,链式存储动态分配内存,但操作起来比顺序存储稍微复杂一些,所以具体内容具体分析,该选择哪一种方式进行存储还需进一步分析;通过一元多项式链式存储和顺序存储的比较与体会,可以体会到对一元多项式链式存储和顺序存储各自的的优缺点和适用性。
一元多项式的运算,包含四个方面,多项式的加、减、乘、除,然而那,在具体计算中,我们需要考虑很多因素。
首先,我们需要判断多项式是否稀疏,其次,考虑对多项式的存储方式(顺序存储或者链式存储),并且,我们还需要保证在计算结果中,不能有重复阶的出现和零项系数的出现,在输出结果时,我们可以让其升序或者降序输出。
本程序用VS2010编写,可以实现对多项式的加减乘的运算,采用顺序存储和链式存储两种方式分别可以进行多项式的加、减、乘的运算以及判断该多项式是否稀疏,最后再将运算结果以升序或者降序排列情况输出。
关键词:
多项式,顺序存储,链式存储,升序降序
引言
1问题的背景分析
为了更好的学习《数据结构》这一门理论和实践性均较强的基础课程,熟练掌握理论知识的同时更需要加强上机的实践。
本课程就是要达到理论和实践相互结合,培养学生的动手能力,在实践中理解各种算法,在创作中提升,使我们能够在数据结构课程中,学会数据结构和算法设计解决问题的思想。
1.1问题的提出
本课程设计主要是探究一元多项式的四则运算,而与此同时,首先,需要我掌握和理解的是对一元多项式的不同的存储方式(链式存储和顺序存储)中,如何有效的对其进行加、减、乘的运算。
其次,需要解决的问题就是给定一个一元多项式,要怎么去判断多项式的稀疏和稠密性。
再者,打印多项式时可如何进行升幂和降幂的打印出多项式。
这些问题都需要我逐一解决。
C语言
C语言既有高级语言的特点,又具有汇编语言的特点;既是一个成功的系统设计语言,有时一个使用的程序设计语言;既能用来编写不依赖计算机硬件的应用程序,又能用来编写各种系统程序;是一种受欢迎、应用广泛的程序设计语言。
C语言发展过程
1973年,美国贝尔实验室的D.M.RITCHIE在B语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,这就是C语言。
1977年DennisM.Ritchie发表了不依赖于具体机器系统的C语言编译文本《可移植的C语言编译程序》。
1978年BrianW.Kernighian和DennisM.Ritchie出版了名著《TheCProgrammingLanguage》,从而使C语言成为目前世界上流行最广泛的高级程序设计语言。
1.2任务与分析
任务是实现求M(x)=Am(x)+Bn(x)、M(x)=Am(x)-Bn(x)和M(x)=Am(x)×Bn(x)。
4)首先判定多项式是否稀疏
5)分别采用顺序和动态存储结构实现;
6)结果M(x)中无重复阶项和无零系数项;
要求输出结果的升幂和降幂两种排列情况
分析:
(1)用一维数组cp1[n1]和cp2[n2]存储一元多项式Am(x)和Bn(x)的系数,用for循环来计算顺序结构中的加法、减法、乘法的结果。
而顺序存储的加减乘运算则分为三个模块函数来解决这三种运算。
(2)用指针*d,*q来存储一元多项式的内容,再利用指针计算动态链表下一元多项式的加法、减法、乘法的结果。
(3)在用降幂升幂两种排列输出结果时,用expn和coef表示一元多项式的系数和指数,输出两种排列结果。
而链式存储的加减乘运算也是分为三个模块函数来解决这三种运算
2系统分析
2.1功能需求
此课题是主要任务是创建一元多项式,并可以选择不同的存储方式对一元多项式进行存储并且可以进行多项式的加、减、乘基本运算,最后将结果可以按照升序或者降序排列。
首先需要创建两个一元多项式,才能继续下一步的进行基本的多项式运算(加、减、乘)。
然后将两种不同的存储方式各自分成一个子快,编写出相应的2个函数(顺序存储、链式存储),然后在主程序里面提示各个选项对相应的功能,用户输入相应的操作数,分别调用不同的函数,打印出相应的排列结果(升幂排列或者降幂排列)。
因此,实际需要设计的任务就是创建一元多项式,以及不同存储方法的函数编写,还有不同存储模式下各自的加减乘的函数编写,为了直观和方便,画出流程图如下图:
一元多项式的计算主流程图1.1:
图1.1一元多项式的计算主流程图
(2)顺序存储结构流程图
如图1.2所示
图1.2顺序存储结构流程图
(3)动态链表结构流程图
如图1.3所示
图1.3动态链表结构流程图
流程图很直观的描述了整个程序服务过程。
2.2总体要求
首先主函数中必须成功创建两个一元多项式,然后查阅资料知道多项式的存储方法,结合数据结构课程,我选择了比较熟悉的顺序存储和链式存储,用户想要对两个多项式进行不同的运算,首先就必须按照先序成功创建一元多项式。
用户要对多项式进行运算,那就需要知道他想怎么运算(加减乘)。
这需要用户手动输入选择序号。
通过用户输入的信息,计算机就可以进行相关的操作,根据用户输入的信息调用对应的函数进行加减乘的运算,最后再按照用户输入的选择升序或者降序输出结果供用户浏览了;我就要用相应的程序去实现这个过程,这才是我最后的目的。
2.3数据需求
输入一元多项式的项数,系数和对应的次数
3、详细设计与实现
3.1设计思路
要完成一元多项式顺序存储和链式存储的加、减、乘这几个基本的运算,有很多种方法可以实现。
但结合数据结构课程,我选择了比较适合自己的算法,其他的算法还有很多,只是都不是很熟悉,我的思想大多都来源于书上,对一元多项式的顺序存储和链式存储的算法做了分析,下一步自然就是完成它的程序了,不能用程序描述出来那在好也没有用的。
详细设计如下:
//定义顺序存储结构类型
intn1,n2;
intcp1[n1];intcp2[n2]
//定义动态链表结构类型
#defineINFEX10000
#defineINFCO10000
doublecoef;
intexpn;
p_pol*next;
//顺序存储结构的抽象数据类型定义
intn1,n2;
利用一维数组cp1[n1]和cp2[n2]存储多项式的系数
//基本操作:
voidcreatpoly1(double*a,intpt)
操作结果:
建立顺序结构
voidaddpoly(double*a,double*b,double*c)
初始条件:
一维数组cp1[n1]和cp2[n2]已建立
操作结果:
顺序结构相加
voidsubpoly(double*a,double*b,double*c)
初始条件:
一维数组cp1[n1]和cp2[n2]已建立
操作结果:
顺序结构相减
voidmulpoly(double*a,double*b,double*c)
初始条件:
一维数组cp1[n1]和cp2[n2]已建立
操作结果:
顺序结构相乘
voidansprint(double*a,intn)
初始条件:
一维数组cp1[n1]和cp2[n2]已建立
操作结果:
选用升幂或降幂排列打印出结果
//动态链表结构的抽象数据类型定义
typedefstructp_pol{doublecoef;intexpn;p_pol*next;}MPP;
基本操作:
MPP*creatlink(MPP*p,intn,intpt)
初始条件:
动态链表已定义
操作结果:
构造动态链表结构
voidaddlink(MPP*p1,MPP*p2,MPP*p3)
初始条件:
动态链表已定义
操作结果:
动态链表相加
voidsublink(MPP*p1,MPP*p2,MPP*p3)
初始条件:
动态链表已定义
操作结果:
动态链表相减
voidmullink(MPP*p1,MPP*p2,MPP*p3)
初始条件:
动态链表已定义
操作结果:
动态链表相乘
voidprintlink(MPP*p)
初始条件:
动态链表已定义
操作结果:
选用升幂或降幂排列打印结果
voiddeletelink(MPP*p)
初始条件:
动态链表已定义
操作结果:
删除结点释放内存
3.2详细编码
//包含头文件
#include"stdafx.h"
#include
#include
#include
#include
#include
#include
#include
usingnamespacestd;
//自定义函数原型说明
voidcreatpoly1(double*a,intpt)//建立顺序结构
voidansprint(double*a,intn)//打印出结果
voidaddpoly(double*a,double*b,double*c,intm,intn)//顺序结构相加
voidsubpoly(double*a,double*b,double*c)//顺序结构相减
voidmulpoly(double*a,double*b,double*c)//顺序结构相乘
MPP*creatlink(MPP*p,intn,intpt)//构造动态链表结构
voidprintlink1(MPP*p)//打印结果Am(x)
voidprintlink2(MPP*p)//打印结果Bn(x)
voidprintlink(MPP*p)//打印结果M(x)
voidaddlink(MPP*p1,MPP*p2,MPP*p3)//动态链表相加
voidsublink(MPP*p1,MPP*p2,MPP*p3)//动态链表相减
voidmullink(MPP*p1,MPP*p2,MPP*p3)//动态链表相乘
voiddeletelink(MPP*p)//删除结点释放内存
//建立顺序结构
顺序存储一元多项式则是通过下标作为指数,系数存储在数组对应的位置,若系数为0,则在其指数对应的数组位置存储的数为0。
voidcreatpoly1(double*a,intpt)//建立顺序结构
{
inti;
if(pt==1)//第一个多项式
{
for(i=0;i<=cp1[n1-1].expn;i++)//把小于等于最大指数的项系数赋值为0
a[i]=0;
for(i=0;ia[cp1[i].expn]=cp1[i].coef;
}
else//第二个多项式
{
for(i=0;i<=cp2[n2-1].expn;i++)//把小于等于最大指数的项系数赋值为0
a[i]=0;
for(i=0;ia[cp2[i].expn]=cp2[i].coef;
}
}
//顺序结构相加,对应的数组下标相同的系数相加
voidaddpoly(double*a,double*b,double*c,intm,intn)//顺序结构相加
{
intmin=(cp1[n1-1].expn>cp2[n2-1].expn?
cp2[n2-1].expn:
cp1[n1-1].expn);//两个多项式的最大指数(较小)
intmax=(cp1[n1-1].expncp2[n2-1].expn:
cp1[n1-1].expn);//两个多项式的最大指数(较大)
inti;
for(i=0;i<=min;i++)//在小于某个多项式的最大指数(较小)的情况下,直接相加
c[i]=a[i]+b[i];
for(;i<=max;i++)//加上剩余的项
if(cp1[n1-1].expn>cp2[n2-1].expn)//如果较小的最大指数在b多项式
c[i]=a[i];
else
{//如果较小的最大指数在a多项式
c[i]=b[i];
}
puts("相加结果为:
");
ansprint(c,max);//输出最后的相加结果
}
//顺序结构相减,对应的数组下标相同的系数相加
voidsubpoly(double*a,double*b,double*c)//顺序结构相减
{
intmin=(cp1[n1-1].expn>cp2[n2-1].expn?
cp2[n2-1].expn:
cp1[n1-1].expn);//两个多项式的最大指数(较小)
intmax=(cp1[n1-1].expncp2[n2-1].expn:
cp1[n1-1].expn);//两个多项式的最大指数(较大)
inti;
for(i=0;i<=min;i++)//在小于某个多项式的最大指数(较小)的情况下,直接相减
c[i]=a[i]-b[i];
for(;i<=max;i++)//处理剩余的项
if(cp1[n1-1].expn>cp2[n2-1].expn)//如果被减数a的最大指数较大
c[i]=a[i];
else//如果减数b的最大指数较大
c[i]=-b[i];
puts("相减结果为:
");
ansprint(c,max);//输出最后的相减结果
}
//顺序结构相乘
voidmulpoly(double*a,double*b,double*c)//顺序结构相乘
{
intmax=cp1[n1-1].expn+cp2[n2-1].expn+2;//计算乘积的项数
inti,j;
for(i=0;ic[i]=0;
for(i=0;i<=cp1[n1-1].expn;i++)//计算剩余的项
for(j=0;j<=cp2[n2-1].expn;j++)
c[i+j]+=a[i]*b[j];
puts("相乘结果为:
");//输出计算的结果
ansprint(c,max-1);
}
经过用户的输入操作,很容易就可以创建出用户需要进行运算的一元多项式,找到对应的存储方式,并弹出菜单项,用户就可以输入选项进行下一步进行加减乘的操作;这样,需要实现的第一个功能就很轻松的完成了。
//动态链表的创建
MPP*creatlink(MPP*p,intn,intpt)//利用动态链表结构存储多项式
{
MPP*d,*q;
inti;
q=(MPP*)malloc(sizeof(MPP));
if(q==NULL)
exit(0);
q->next=NULL;//初始化指针为NULL
q->coef=INFCO;/初始化初始系数
q->expn=-INFEX;//初始化初始指数
p=q;
for(i=0;i{
d=(MPP*)malloc(sizeof(MPP));
if(d==NULL)
exit(0);
d->next=NULL;
if(pt==1)//第一个多项式
{
d->coef=cp1[i].coef;//多项式系数
d->expn=cp1[i].expn;//多项式指数
}
else
//第二个多项式
{
d->coef=cp2[i].coef;//多项式系数
d->expn=cp2[i].expn;//多项式指数
}
q->next=d;//继续下一个结点
q=d;
}
returnp;
}
//打印结果,用户可选择升幂或者降幂打印,如若用户输入的选项不正确,则系统默认升幂打印出结果。
voidprintlink(MPP*p)//打印结果M(x)
{
intnum=0,i=0,choose,count=0;
puts("请选择输出顺序:
1升幂2降幂:
");
scanf_s("%d",&choose);//输入打印格式选项
MPP*tp=p;
p=p->next;
while(p!
=NULL)//计算结点个数
{
num++;
p=p->next;
}
MPOL*d=newMPOL[num];//建立输出数据结构
p=tp->next;
while(p!
=NULL)//对新建的数据结构赋值
{
d[i].coef=p->coef;
d[i].expn=p->expn;
i++;
p=p->next;
}
if(choose==2)//降幂打印多项式
{
count=0;
printf("M(X)=");
for(i=num-1;i>=0;i--)
{
if(d[i].coef>0)
putchar('+');
printf("%lfX^%d",d[i].coef,d[i].expn);
}
}
else//升幂打印多项式
{
if(choose!
=1)
printf("没有%d选项,系统将默认输出升序:
\nM(X)=",choose);
else
printf("M(X)=");
for(i=0;i{
if(d[i].coef>0)
putchar('+');
printf("%lfX^%d",d[i].coef,d[i].expn);
}
}
putchar(10);
}
//动态链表相加,即比较对应的指数,如若相同,则系数相加
voidaddlink(MPP*p1,MPP*p2,MPP*p3)//动态链表相加
{
MPP*p,*head;
p=(MPP*)malloc(sizeof(MPP));//建立动态链表
if(p==NULL)
exit(0);
//初始化链表数据
p->coef=INFCO;
p->expn=-INFEX;
p->next=NULL;
head=p3=p;
p1=p1->next;
p2=p2->next;
while(p1!
=NULL||p2!
=NULL)//两个链表相加,两个链表到表尾时结束循环
{
if(fabs(head->coef)>1e-8)
{
p=(MPP*)malloc(sizeof(MPP));//创建结点
if(p==NULL)
exit(0);
head->next=p;
head=p;
head->next=NULL;
}
if(p1==NULL