长整数的代数计算数据结构课程设计.docx
《长整数的代数计算数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《长整数的代数计算数据结构课程设计.docx(27页珍藏版)》请在冰豆网上搜索。
长整数的代数计算数据结构课程设计
沈阳航空航天大学
课程设计报告
课程设计名称:
数据结构课程设计
课程设计题目:
长整数的代数计算
院(系):
计算机学院
专业:
计算机科学与技术
班级:
学号:
姓名:
指导教师:
1题目介绍和功能要求1
题目介绍1
功能要求1
基本功能1
2系统功能模块结构图2
系统功能结构框图2
系统主要模块的功能说明2
3使用的数据结构的描述4
数据结构设计4
数据结构用法说明4
4函数的描述5
主要函数设计5
主要函数流程图6
5程序测试和运行的结果11
程序测试11
运行结果12
6参考文献14
附录(关键部分程序清单)15
1题目介绍和功能要求
题目介绍
设计数据结构完成长整数的表示和存储,并编写算法来实现两个长整数的加、减、乘、除等基本代数运算。
功能要求
1)长整数长度在一百位以上。
2)实现两长整数在同余代数下的加、减、乘、除操作。
即实现算法来求解
a+bmodn,a-bmodn,a*bmodn,a\bmodn。
3)输入输出均在文件中。
(选作)
基本功能
1.jiafa();
将一百位以上的长整数进行加法运算,计算出和。
2.jianfa();
将一百位以上的长整数进行减法运算,计算出差。
3.chenfa();
将一百位以上的长整数进行乘法运算,计算出积。
4.chufa();
将一百位以上的长整数进行除法运算,计算出商和余数。
2系统功能模块结构图
系统功能结构框图
图系统功能结构框图
系统主要模块的功能说明
1.主模块
kongzhi();
控制输入模块、加法模块、减法模块、乘法模块、除法模块、输出模块的循环使用。
2.输入模块
shuru();
将输入的两组长整数分别通过转换将其转换成所需要的形式存储到两个链表(opr1、opr2)中保存起来。
3.加法模块
jiafa();
将链表opr1、opr2中的数据进行加法运算,并且二者的将加和保存到链表oprr中。
4.减法模块
jianfa();
将链表opr1、opr2中的数据进行减法运算,并且将二者的差保存到链表oprr中。
5.乘法模块
chengfa();
将链表opr1、opr2中的数据进行乘法运算,并且将二者的乘积保存到链表oprr中。
6.除法模块
chufa();
将链表opr1、opr2中的数据进行加法运算,并且将二者的商和余数分别保存到链表quti、remand中。
7.输出模块
shuchu();
将链表oprr、quti、remand中的数据保存到字符数组中,并且将字符数组中的数据输出到屏幕上。
3使用的数据结构的描述
数据结构设计
将输入的两个长整数首先保持到字符数组中,然后将字符数组中的字符转换每四个一组,利用双向循环链表来实现每一组字符的存储,并且高位在前、低位在后。
每个结点中只存储四位十进制数字,即不超过9999的非负整数。
利用两个双向循环链表分别保持了两个非负长整数。
加法:
由低位的结点开始相加,加和大于9999时,加和除以一万取余数保存到新的双向循环链表结点中,并且加和除以一万取整数作为进位加到下两个结点相加中,依次循环相加;减法:
同加法有些相似,保证第一个长整数不小于于第二个长整数,结点相减,不能相减就相前一结点借位,差保存到新的双向循环链表结点中,依次循环;乘法:
由低位的结点开始相乘,乘积大于9999时,乘积除以一万取余数保存到新的双向循环链表结点中,并且乘积除以一万取整数作为进位加到下两个结点乘积中,依次循环相乘;除法:
开辟两个新的链表,保存商数和差。
用第一个长整数循环减去第二个长整数,没减一次计数加一,计数保存到商数链表中。
直到差小于第二个长整数停止循环,最后的计数为商值,差值为余数。
选择该数据结构来完成长整数的加减乘除运算是因为要对长整数进行运算,需要对长整数进行存储,所以选择用链表对长整数存储,又由于存储的顺序是从左到右,而运算的顺序则是从右到左,这样位了操作方便选择循环链表,在运算过程中有进位和借位的操作,所以最终选择双向循环链表的数据结构。
数据结构用法说明
输入的两个长整数必须为非负长整数。
加法计算时只要保证两个数都为非负数即可,减法、乘法、除法时需要保证第一个长整数大于第二个长整数。
同时乘法、除法计算时第二个数不能为零,并且输入的数一定要合法,最高位不能为零,否则程序会提示输入有误。
4函数的描述
4.1主要函数设计
1.shuru();
作用:
将输入的两个长整数分别保存到两个链表中。
2.jiafa();
作用:
将两个长整数进行加法运算,计算出二者的和。
3.jianfa();
作用:
将两个长整数进行减法运算,计算出二者的差。
4.chengfa();
作用:
将两个长整数进行乘法运算,计算出二者的积。
5.chufa();
作用:
将两个长整数进行除法运算,计算出二者的商和余数。
6.shuchu();
作用:
将保存到链表中的计算结果输出。
主要函数流程图
1.kongzhi():
图控制函数流程图
2.jiafa();
图加法函数流程图
3.jianfa();
图减法函数流程图
4、chengfa();
图乘法函数流程图
5、chufa();
图除法函数流程图
5程序测试和运行的结果
程序测试
1、程序开始菜单:
图菜单图
2、程序退出:
图退出程序图
运行结果
1、加法运算:
图除法运算图
2、减法运算:
图除法运算图
3、乘法运算:
图除法运算图
4、除法运算:
图除法运算图
6参考文献
[1]谭浩强着.C程序设计(第三版).北京:
清华大学出版社,2005
[2]严蔚敏吴伟明.数据结构(C语言版).北京:
清华大学出版社,2007
[3]王裕明.数据结构与程序设计.北京:
清华大学出版社,2010
[4]谭浩强.C语言程序设计[M].北京:
清华大学出版社,2005
[5]王敬华林萍张清国.C语言程序设计教程[M].北京:
清华大学出版社,2005
附录(关键部分程序清单)
#include""
#include<>
#include<>
#include<>
#include<>
#defineLENsizeof(structNode)
#defineMAX1000
#defineOK1
#defineERROR0
#defineOVERFLOW-1
#defineTRUE1
#defineFALSE0
typedefintStatus;
typedefstructNode
{intdata;
structNode*prior,*next;
}Node,*NodeList;
intaxp(inta,intk)........................
p1=p1->prior;
p2=p2->prior;
}
while(p1!
=opr1)
{........................
p1=p1->prior;
}
while(p2!
=opr2)
{//处理opr2链的剩余部分
buffer=p2->data+CF;
CF=buffer/10000;//若buffer的值大于9999则产生进位,赋给CF
//将新建结点插入到头结点之后
p3=(NodeList)malloc(LEN);
oprr->next->prior=p3;
p3->prior=oprr;
p3->next=oprr->next;
oprr->next=p3;
p3->data=buffer%10000;
p2=p2->prior;
}
if(CF)
{
p3=(NodeList)malloc(LEN);
oprr->next->prior=p3;
p3->prior=oprr;
p3->next=oprr->next;
oprr->next=p3;
p3->data=CF;
}
returnOK;
}
//===================减法基本操作==========================
Statusjianfa(NodeListopr1,NodeListopr2,NodeList&oprr)//本算法实现A,B相减的操作
{
//将A链分成与B链长相等的底位部分,和剩余的高位部分,并做相应处理。
intCF,buffer,flag;
NodeListp1,p2,p3,qh,qt,qq;
oprr=(NodeList)malloc(LEN);
oprr->next=oprr;
oprr->prior=oprr;
p1=opr1->prior;
p2=opr2->prior;
CF=buffer=flag=0;
while(p2!
=opr2)//opr2链的长度小于等于opr1链的
{
if(p1->data<(p2->data+CF))
{
buffer=10000+p1->data-(p2->data+CF);
CF=1;
}
else
{
buffer=p1->data-(p2->data+CF);
CF=0;
}
p3=(NodeList)malloc(LEN);
oprr->next->prior=p3;
p3->prior=oprr;
p3->next=oprr->next;
oprr->next=p3;
p3->data=buffer;
p1=p1->prior;
p2=p2->prior;
}
while(p1!
=opr1)
{//处理opr1链剩下的部分
if(p1->data{
buffer=10000+p1->data-CF;
CF=1;
}
else
{
buffer=p1->data-CF;
CF=0;
}
p3=(NodeList)malloc(LEN);
oprr->next->prior=p3;
p3->prior=oprr;
p3->next=oprr->next;
oprr->next=p3;
p3->data=buffer;
p1=p1->prior;
}
//处理链表开头结点值为0的无意义情况,若链表本身表示0,则不做如下处理
p3=oprr->next;
while(p3->data==0&&p3->next!
=oprr)
{
p3=p3->next;
flag=1;
}
if(flag)
{
qh=oprr->next;//保存无用结点的头尾指针
qt=p3->prior;//为释放做准备
oprr->next=p3;//重接next链
p3->prior=oprr;//重接prior链
qt->next=NULL;
while(qh!
=NULL)
{//释放无用结点
qq=qh;
qh=qh->next;
free(qq);
}
}
returnOK;
}
//========================乘法模块===========================
Statuschengfa(NodeListopr1,NodeListopr2,NodeList&oprr)
{
NodeListph1,ph2,pt1,pt2,p3,pt3,qq;
intlen,CF;
longbuffer;
ph1=opr1;
pt1=ph1->prior;
ph2=opr2;
pt2=ph2->prior;
len=length(opr1)+length(opr2);
Creat(oprr,len);
qq=oprr->next;
while(qq!
=oprr)
{
qq->data=0;
qq=qq->next;
}
buffer=CF=0;
p3=oprr->prior;
while(pt2!
=ph2)
{
pt1=ph1->prior;
pt3=p3;
while(pt1!
=ph1)
{
buffer=pt1->data*pt2->data+pt3->data+CF;
CF=(int)buffer/10000;
pt3->data=(int)buffer%10000;
pt1=pt1->prior;
pt3=pt3->prior;
}
pt3->data=CF;
CF=0;
pt2=pt2->prior;
p3=p3->prior;
}
returnOK;
}
//======================除法模块=======================
//除法子函数
intchufa_zi(NodeList&opr1,NodeListopr2)
{
NodeListp1,p2,qh,qt,qq;
intcount,CF,buffer,flag;
count=0;
while(compare(opr1,opr2)!
=-1)//opr2链长
{
CF=buffer=0;
p1=opr1->prior;
p2=opr2->prior;
while(p2!
=opr2)
{
if(p1->data<(p2->data+CF))
{
buffer=10000+p1->data-(p2->data+CF);
CF=1;
}
else
{
buffer=p1->data-(p2->data+CF);
CF=0;
}
p1->data=buffer;
p1=p1->prior;
p2=p2->prior;
}
if(p1!
=opr1)//处理opr1链剩下的部份
{
buffer=p1->data-CF;
p1->data=buffer;
}
//清头0
flag=0;
p1=opr1->next;
while(p1->data==0&&p1->next!
=opr1)
{
p1=p1->next;
flag=1;
}
if(flag)
{
qh=opr1->next;//保存无用结点的头尾指针
qt=p1->prior;//为释放做准备
opr1->next=p1;//重接next链
p1->prior=opr1;//重接prior链
qt->next=NULL;
while(qh!
=NULL)
{//释放无用结点
qq=qh;
qh=qh->next;
free(qq);
}
}
count++;
}
returncount;
}
//除法函数
Statuschufa(NodeListopr1,NodeListopr2,NodeList&quti,NodeList&remand)
{//quti为商数链,remand为余数链
intlen_quti,len_reman,buffer;
NodeListq1,q2,pq;
if(compare(opr1,opr2)==-1)//除数比被除数大
{
Creat(quti,1);
quti->next->data=0;
quti->next->next=quti;
quti->prior=quti->next;
remand=opr1;
}
else
{
len_quti=length(opr1)-length(opr2);
len_reman=length(opr2);
Creat(quti,len_quti+1);//开辟商数链
Creat(remand,len_reman);//开辟余数链
q1=opr1->next;
q2=remand->next;//q2指向余数链remand的下一结点
//初始化remand链
while(q2!
=remand)
{
q2->data=q1->data;
q1=q1->next;
q2=q2->next;
}
pq=quti->next;
q1=q1->prior;//指针退回一步
while(q1!
=opr1)
{
buffer=chufa_zi(remand,opr2);
pq->data=buffer;
if(q1->next!
=opr1)
{
remand->prior->next=(NodeList)malloc(LEN);
remand->prior->next->next=remand;
remand->prior->next->prior=remand->prior;
remand->prior=remand->prior->next;
remand->prior->data=q1->next->data;
}
if(remand->next->data==0&&remand->next->next!
=remand)
{
remand->next->next->prior=remand;
remand->next=remand->next->next;
}
q1=q1->next;
pq=pq->next;
}
pq=quti->prior;
while(pq->data=='')
pq=pq->prior;
pq->next=quti;
quti->prior=pq;
}
returnOK;
}
//=========================主操作模块=========================
Statuskongzhi()
{
NodeListopr1,opr2,oprr,quti,remand;
charstr[MAX],ch;
opr1=opr2=oprr=quti=remand=NULL;
printf("========================================================\n");
printf("欢迎使用长整数代数计算程序\n");
printf("\n=================本程序的操作提示========================\n");
printf("================选择1将会进行加法操作===================\n");
printf("================选择2将会进行减法操作===================\n");
printf("================选择3将会进行乘法操作==================\n");
printf("================选择4将会进行除法操作==================\n");
printf("================选择5将会退出本程序==================\n");
printf("请选择:
");
ch=getche();
while(ch>'5'||ch<'1')
{
printf("没有对应的操作选项,请重新选择:
\n");
ch=getchar();getchar();
}
switch(ch)
{
case'1':
shuru(opr1,opr2,str);
printf("\n相加的和为:
\n");
jiafa(opr1,opr2,oprr);
shuchu(oprr,str);break;
case'2':
shuru(opr1,opr2,str);
printf("\n相减的差为:
\n");
jianfa(opr1,opr2,oprr);
shuchu(oprr,str);break;
case'3':
shuru(opr1,opr2,str);
printf("\n相乘的积为:
\n");
chengfa(opr1,opr2,oprr);
shuchu(oprr,str);break;
case'4':
shuru(opr1,opr2,str);
while(opr2->next->data==0)
{
printf("\n除数不能为0!
,请重新输入:
\n");
scanf("%s",str);
zhuanhuan(str,opr2);
}
printf("\n商数为:
\n");
chufa(opr1,opr2,quti,remand);
shuchu(quti,str);
printf("\n余数为:
\n");
shuchu(remand,str);break;
case'5':
exit(0);
}
returnOK;
}
//主函数
intmain()
{
intflag=1;
charch;
while(flag)
{
kongzhi();
printf("\n继续(Y/N)");
ch=getchar();
getchar();
if(ch=='N'||ch=='n')
flag=0;
system("cls");
}
return0;
}
课程设计总结:
首先,通过此次数据结构课程设计,让我知道原来我们身边许多东西离我们并不遥远,有很多东西是我们是靠我们不断努力探索创造出来的。
其次,此次课程设计,感慨颇多。
的确,自从拿到题目到完成整个编程,从理论到实践,在做课设的这些的日子里,可以学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得