长整数代数计算数据结构课程设计.docx

上传人:b****6 文档编号:8741639 上传时间:2023-02-01 格式:DOCX 页数:30 大小:283.95KB
下载 相关 举报
长整数代数计算数据结构课程设计.docx_第1页
第1页 / 共30页
长整数代数计算数据结构课程设计.docx_第2页
第2页 / 共30页
长整数代数计算数据结构课程设计.docx_第3页
第3页 / 共30页
长整数代数计算数据结构课程设计.docx_第4页
第4页 / 共30页
长整数代数计算数据结构课程设计.docx_第5页
第5页 / 共30页
点击查看更多>>
下载资源
资源描述

长整数代数计算数据结构课程设计.docx

《长整数代数计算数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《长整数代数计算数据结构课程设计.docx(30页珍藏版)》请在冰豆网上搜索。

长整数代数计算数据结构课程设计.docx

长整数代数计算数据结构课程设计

沈阳航空航天大学

 

课程设计报告

 

课程设计名称:

数据结构课程设计

课程设计题目:

长整数的代数计算

 

院(系):

计算机学院

专业:

计算机科学与技术

班级:

学号:

姓名:

指导教师:

 

1题目介绍和功能要求

1.1题目介绍

设计数据结构完成长整数的表示和存储,并编写算法来实现两个长整数的加、减、乘、除等基本代数运算。

1.2功能要求

1)长整数长度在一百位以上。

2)实现两长整数在同余代数下的加、减、乘、除操作。

即实现算法来求解

a+bmodn,a-bmodn,a*bmodn,a\bmodn。

3)输入输出均在文件中。

(选作)

1.3基本功能

1.jiafa();

将一百位以上的长整数进行加法运算,计算出和。

2.jianfa();

将一百位以上的长整数进行减法运算,计算出差。

3.chenfa();

将一百位以上的长整数进行乘法运算,计算出积。

4.chufa();

将一百位以上的长整数进行除法运算,计算出商和余数。

2系统功能模块结构图

2.1系统功能结构框图

图2.1系统功能结构框图

2.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使用的数据结构的描述

3.1数据结构设计

将输入的两个长整数首先保持到字符数组中,然后将字符数组中的字符转换每四个一组,利用双向循环链表来实现每一组字符的存储,并且高位在前、低位在后。

每个结点中只存储四位十进制数字,即不超过9999的非负整数。

利用两个双向循环链表分别保持了两个非负长整数。

加法:

由低位的结点开始相加,加和大于9999时,加和除以一万取余数保存到新的双向循环链表结点中,并且加和除以一万取整数作为进位加到下两个结点相加中,依次循环相加;减法:

同加法有些相似,保证第一个长整数不小于于第二个长整数,结点相减,不能相减就相前一结点借位,差保存到新的双向循环链表结点中,依次循环;乘法:

由低位的结点开始相乘,乘积大于9999时,乘积除以一万取余数保存到新的双向循环链表结点中,并且乘积除以一万取整数作为进位加到下两个结点乘积中,依次循环相乘;除法:

开辟两个新的链表,保存商数和差。

用第一个长整数循环减去第二个长整数,没减一次计数加一,计数保存到商数链表中。

直到差小于第二个长整数停止循环,最后的计数为商值,差值为余数。

选择该数据结构来完成长整数的加减乘除运算是因为要对长整数进行运算,需要对长整数进行存储,所以选择用链表对长整数存储,又由于存储的顺序是从左到右,而运算的顺序则是从右到左,这样位了操作方便选择循环链表,在运算过程中有进位和借位的操作,所以最终选择双向循环链表的数据结构。

3.2数据结构用法说明

输入的两个长整数必须为非负长整数。

加法计算时只要保证两个数都为非负数即可,减法、乘法、除法时需要保证第一个长整数大于第二个长整数。

同时乘法、除法计算时第二个数不能为零,并且输入的数一定要合法,最高位不能为零,否则程序会提示输入有误。

4函数的描述

4.1主要函数设计

1.shuru();

作用:

将输入的两个长整数分别保存到两个链表中。

2.jiafa();

作用:

将两个长整数进行加法运算,计算出二者的和。

3.jianfa();

作用:

将两个长整数进行减法运算,计算出二者的差。

4.chengfa();

作用:

将两个长整数进行乘法运算,计算出二者的积。

5.chufa();

作用:

将两个长整数进行除法运算,计算出二者的商和余数。

6.shuchu();

作用:

将保存到链表中的计算结果输出。

 

4.2主要函数流程图

1.kongzhi():

图4.2.1控制函数流程图

 

2.jiafa();

图4.2.2加法函数流程图

3.jianfa();

图4.2.3减法函数流程图

4、chengfa();

图4.2.4乘法函数流程图

5、chufa();

图4.2.5除法函数流程图

5程序测试和运行的结果

5.1程序测试

1、程序开始菜单:

图5.1.1菜单图

2、程序退出:

图5.1.2退出程序图

 

5.2运行结果

1、加法运算:

图5.2.1除法运算图

 

2、减法运算:

图5.2.2除法运算图

 

3、乘法运算:

图5.2.3除法运算图

4、除法运算:

图5.2.4除法运算图

6参考文献

[1]谭浩强著.C程序设计(第三版).北京:

清华大学出版社,2005

[2]严蔚敏吴伟明.数据结构(C语言版).北京:

清华大学出版社,2007

[3]王裕明.数据结构与程序设计.北京:

清华大学出版社,2010

[4]谭浩强.C语言程序设计[M].北京:

清华大学出版社,2005

[5]王敬华林萍张清国.C语言程序设计教程[M].北京:

清华大学出版社,2005

附录(关键部分程序清单)

#include"stdafx.h"

#include

#include

#include

#include

#defineLENsizeof(structNode)

#defineMAX1000

#defineOK1

#defineERROR0

#defineOVERFLOW-1

#defineTRUE1

#defineFALSE0

typedefintStatus;

typedefstructNode

{intdata;

structNode*prior,*next;

}Node,*NodeList;

intaxp(inta,intk)//求指数函数值

{

intr=1;

if(k==0)

return1;

for(;k>0;k--)

r=r*a;

returnr;

}

Statuszhuanhuan(charstr[],NodeList&oprh)//输入转换函数

{//将字符串形式的操作数转换成所需的类型

NodeListp;

inti,k,buffer;

k=buffer=0;

oprh=(NodeList)malloc(LEN);

oprh->next=oprh;

oprh->prior=oprh;

for(i=strlen(str)-1;i>=0;i--)

{

if((i!

=0||(str[0]!

='-'&&str[0]!

='+'))&&(str[i]>'9'||str[i]<'0'))//判断输入是否合法

returnERROR;

if(str[0]=='0'&&str[1]!

='\0')

returnERROR;

if((str[0]=='-'||str[0]=='+')&&str[1]=='0')

returnERROR;

if(str[i]!

='-'&&str[i]!

='+')

{

buffer=buffer+(str[i]-'0')*axp(10,k);

k++;

if(k==4||str[i-1]=='-'||str[i-1]=='+'||i==0)

{

p=(NodeList)malloc(LEN);//将新建结点插入到头结点之后

oprh->next->prior=p;

p->prior=oprh;

p->next=oprh->next;

oprh->next=p;

p->data=buffer;

buffer=k=0;

}

}

}

returnOK;

}

Statusshuru(NodeList&opr1,NodeList&opr2,charstr[])//输入函数

{

intflag=OK;

printf("\n\n请输入第一个操作数:

\n");

scanf("%s",str);

getchar();

flag=zhuanhuan(str,opr1);

while(!

flag)

{

printf("整数输入有误,请重新输入:

\n");

scanf("%s",str);

getchar();

flag=zhuanhuan(str,opr1);

}

printf("\n\n请输入第二个操作数:

\n");

scanf("%s",str);

getchar();

flag=zhuanhuan(str,opr2);

while(!

flag)

{

printf("整数输入有误,请重新输入:

\n");

scanf("%s",str);

getchar();

flag=zhuanhuan(str,opr2);

}

returnOK;

}

//输出函数

Statusshuchu(NodeListoprr,charstr[])

{

Statusinitbuf(charstr[]);

NodeListp;

inti,j,num[4];

if(!

oprr)

returnERROR;

p=oprr;

i=j=0;

initbuf(str);

p=p->next;

if(p->next==oprr&&p->data==0)//若要输出的数为0则执行

str[i++]='0';

else

while(p!

=oprr)

{

num[0]=p->data/1000;

num[1]=(p->data-num[0]*1000)/100;

num[2]=(p->data-num[0]*1000-num[1]*100)/10;

num[3]=p->data-num[0]*1000-num[1]*100-num[2]*10;

while(j<4)

{

if(num[j]!

=0||(str[0]=='-'&&str[1]!

='\0')||(str[0]!

='-'&&str[0]!

='\0'))//此判断语句是为了避免输出诸如:

00123…的情况

str[i++]=num[j]+'0';//

j++;

}

p=p->next;

j=0;

}

str[i]='\0';

printf("%s",str);

printf("\n");

returnOK;

}

Statusinitbuf(charstr[])//缓冲区部分初始化函数

{

inti;

for(i=0;i<=10;i++)

str[i]='\0';

returnOK;

}

intcmplinklen(NodeListopr1,NodeListopr2)//比较链表长度函数

{//opr1链比opr2链长则返回1,短则返回-1,相等则返回0

NodeListp1,p2;

p1=opr1->prior;

p2=opr2->prior;

while(p1->prior!

=opr1&&p2->prior!

=opr2)

{

p1=p1->prior;

p2=p2->prior;

}

if(p1->prior!

=opr1)

return1;

if(p2->prior!

=opr2)

return-1;

return0;

}

intlength(NodeListoprr)//求链表长度

{

intcount=0;

NodeListp=oprr->next;

while(p!

=oprr)

{

count++;

p=p->next;

}

returncount;

}

StatusCreat(NodeList&oprr,intlen)//生成指定长度链表

{

NodeListp;

oprr=(NodeList)malloc(LEN);

p=oprr;

while(len>0)

{

p->next=(NodeList)malloc(LEN);

p->next->data='?

';

p->next->prior=p;

p=p->next;

len--;

}

p->next=oprr;

oprr->prior=p;

returnOK;

}

intcompare(NodeListopr1,NodeListopr2)//比较opr1、opr2绝对值的大小

{

NodeListp1,p2;

p1=opr1->next;

p2=opr2->next;

if(cmplinklen(opr1,opr2)==1)//opr1比较长

return1;

elseif(cmplinklen(opr1,opr2)==-1)//opr2比较长

return-1;

else//长度相等的情况

{

while(p1->data==p2->data&&p1->next!

=opr1)

{

p1=p1->next;

p2=p2->next;

}

if(p1->data>p2->data)

return1;

elseif(p1->datadata)

return-1;

else

return0;

}

}

//-----------------------初始化链表函数-----------------------

Statusinit(NodeList&oppr)

{

oppr=NULL;

returnOK;

}

//===========================加法模块==========================

Statusjiafa(NodeListopr1,NodeListopr2,NodeList&oprr)//本算法实现A,B相加的操作

{

intCF,buffer;

NodeListp1,p2,p3;

oprr=(NodeList)malloc(LEN);

oprr->next=oprr;

oprr->prior=oprr;

p1=opr1->prior;

p2=opr2->prior;

CF=buffer=0;

while(p1!

=opr1&&p2!

=opr2)

{

buffer=p1->data+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;//应该将buffer的第四位赋给p3->data

//..........................

p1=p1->prior;

p2=p2->prior;

}

while(p1!

=opr1)

{//处理opr1链的剩余部分

buffer=p1->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;

//..........................

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;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1