长整数四则运算加减法.docx

上传人:b****8 文档编号:9547434 上传时间:2023-02-05 格式:DOCX 页数:23 大小:198.67KB
下载 相关 举报
长整数四则运算加减法.docx_第1页
第1页 / 共23页
长整数四则运算加减法.docx_第2页
第2页 / 共23页
长整数四则运算加减法.docx_第3页
第3页 / 共23页
长整数四则运算加减法.docx_第4页
第4页 / 共23页
长整数四则运算加减法.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

长整数四则运算加减法.docx

《长整数四则运算加减法.docx》由会员分享,可在线阅读,更多相关《长整数四则运算加减法.docx(23页珍藏版)》请在冰豆网上搜索。

长整数四则运算加减法.docx

长整数四则运算加减法

青岛理工大学

数据结构课程设计报告

题目:

长整数四则运算

院(系):

计算机工程学院

学生姓名:

班级:

学号:

起迄日期:

指导教师:

房斐斐

 

2012—2013年度第2学期

一、需求分析

1.问题描述:

设计一个实现任意长的整数进行加、减法运算的演示程序。

2.基本功能

1、本程序实现计算任意长的整数的加、减法运算.以用户和计算机对话的方式,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令,然后程序就计算并显示出这两个数的运算。

2、本演示程序中,集合的元素限定为数字字符[‘0’~’9’]和字符‘,’与‘;’,输入字符可以任意长,输入形式以“回车符”为结束标志,串中字符顺序不限,且允许出现重复字符。

3、利用双向循环链表现实长整数的存储,每个结点含一个整形变量。

输入的形式以回车结束,可以直接输入正数或负数。

按中国对于长整数的表示习惯,每四位一组,除数字和位于首位置的负号外,其它一切字符都将作为分隔符,连续多个分隔符当一个处理。

但不使用分隔符也不影响结果。

3.输入输出

(1)0;0;加法应输出“0”,减法应输出”0”。

(2)-2345,6789;-7654,3211;加法应输出“-1,0000,0000”,减法应输出”5408,6422”。

(3)-9999,9999;1,0000,0000,0000;加法应输出“9999,0000,0001”,减法应输出1,0000,9999,9999。

(4)1,0001,0001;-1,0001,0001;加法应输出“0”,减法应输出”2,0002,0002”。

(5)1,0001,0001;-1,0001,0000;加法应输出“1”,减法应输出”2,0002,0001”。

(6)-9999,9999,9999;-9999,9999,9999;加法应输出“1,9999,9999,9998”,减法应输出”0”。

(7)1,0000,9999,9999;1;加法应输出“1,0001,0000,0000”,减法应输出”1,0000,9999,9998”。

二、概要设计

1.设计思路:

(1)利用双向循环链表现实长整数的存储,每个结点中可以存放的最大整数为32767,才能保证两数相加不会溢出,但若这样存放,即相当于按32768进制存放,在十进制与32768进制数之间的转换十分不方便,故可以在每个结点中仅存十进制的4位,即不超过9999的非负整数,整个链表表示为万进制。

(2)可以利用头结点数据域的符号代表长整数的符号。

用其绝对值表示元素结点数目。

相加过程中不要破坏两个操作数链表。

两操作数的头指针存于指针数组中是简化程序结构的一种方法。

不能给长整数位数规定上限。

2.数据结构设计:

1)数据类型:

typedefintDataType;//定义数据类型

typedefstructDoubleNode//定义链表元素

{

DataTypedata;

structDoubleNode*prior;

structDoubleNode*next;

}DLNode;

2)存储结构:

顺序结构,链式存储。

采用链式存储的方式会方便字符的读入和操作,且算法简单易懂。

3.软件结构设计:

1)初始化链表

voidInitNode(DLNode**head)

2)向链表第n个位置插入元素X

intInsertNode(DLNode*head,intn,DataTypex)

3)判断整数N有几位

intdigit(intn)

4)两数相加

voidadd(DLNode*h1,DLNode*h2)

5)两数相减

voidjian(DLNode*h1,DLNode*h2)

6)打印链表

voidPrintNode(DLNode*head)

7)删除链表

voidDestroyNode(DLNode**head)

8)主函数

intmain()

三、详细设计

数据类型。

typedefintDataType;//定义数据类型

typedefstructDoubleNode//定义链表元素

{

DataTypedata;

structDoubleNode*prior;

structDoubleNode*next;

}DLNode;

2.存储结构类型:

voidInitNode(DLNode**head)//初始化链表

{

if((*head=(DLNode*)malloc(sizeof(DLNode)))==NULL)

exit

(1);

(*head)->prior=*head;

(*head)->next=*head;

}

3.主函数和其他函数的伪码算法;

1.主函数:

intmain()//主函数

{

DLNode*head1,*head2;

chardata1[N],data2[N];

chard1[10],d2[10];

inti,j,k;

intxun;

printf("提示:

较长的字符串数作为被加数,如果等长,则第一个数加第二个数\n\n");

while

(1)

{

printf("输入数据:

\n");

scanf("%s%s",data1,data2);

InitNode(&head1);

InitNode(&head2);

i=0;

k=0;

while(data1[i]!

=';')//将数1用链表储存

{

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

d1[j]=0;

j=0;

while(data1[i]!

=';'&&data1[i]!

=',')

d1[j++]=data1[i++];

if(data1[i]==',')

i++;

if(data1[0]=='-')//处理正负数

j=-(int)fabs(atoi(d1));//atoi()把字符串转换成整型数,头文件:

#include

else

j=atoi(d1);

InsertNode(head1,k++,j);

}

i=0;

k=0;

while(data2[i]!

=';')//将数2用链表储存

{

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

d2[j]=0;

j=0;

while(data2[i]!

=';'&&data2[i]!

=',')

d2[j++]=data2[i++];

if(data2[i]==',')

i++;

if(data2[0]=='-')//处理正负数

j=-(int)fabs(atoi(d2));

else

j=atoi(d2);

InsertNode(head2,k++,j);

}

printf("选择加减法:

1—加法,0—退出\n");

scanf("%d",&xun);

if(xun==0)

break;

switch(xun)

{

case1:

if(strlen(data1)>=strlen(data2))//较长的数作为被加数

add(head1,head2);

elseadd(head2,head1);

break;

default:

break;

}

DestroyNode(&head1);

DestroyNode(&head2);

printf("\n\n");

}

return0;

}

 

2.初始化链表:

voidInitNode(DLNode**head)//初始化链表

{

if((*head=(DLNode*)malloc(sizeof(DLNode)))==NULL)

exit

(1);

(*head)->prior=*head;

(*head)->next=*head;

}

 

3.向链表第n个位置插入元素X

intInsertNode(DLNode*head,intn,DataTypex)//向链表第n个位置插入元素X

{

DLNode*p,*nt;

inti=0;

p=head->next;

while(p!

=head&&i

{

p=p->next;

i++;

}

if(i!

=n)

{

printf("插入位置错误\n");

return0;

}

if((nt=(DLNode*)malloc(sizeof(DLNode)))==NULL)

exit

(1);

nt->data=x;

nt->prior=p->prior;

nt->prior->next=nt;

nt->next=p;

p->prior=nt;

return1;

}

 

4.判断整数N有几位

intdigit(intn)//判断整数N有几位

{

inti;

for(i=1;;n/=10,i++)

{

if(n/10==0)

returni;

}

}

5.打印链表

voidPrintNode(DLNode*head)//打印链表

{

printf("结果是:

");

DLNode*p=head->prior;

inti;

while(p->data==0)//去掉前面的一串0

{

p=p->prior;

if(p==head)

{

printf("0\n");

return;

}

}

printf("%d",p->data);//最前面的一个数进行特殊处理,不用补零

p=p->prior;

while(p!

=head)//打印后面的数字

{

printf(",");

if(p->data==0)

{

printf("0000");

p=p->prior;

continue;

}

for(i=0;i<4-digit(p->data);i++)//补零

printf("0");

printf("%d",p->data);

p=p->prior;

}

printf("\n");

}

 

6.删除链表

voidDestroyNode(DLNode**head)

{

DLNode*p,*p1;

p=(*head)->next;

while(p!

=*head)

{

p1=p;

p=p->next;

free(p1);

}

free(p);

head=NULL;

}

 

7.两数相加

voidadd(DLNode*h1,DLNode*h2)

{

inti=0,j=0;

DLNode*head3;

InitNode(&head3);

DLNode*p1=h1->prior,*p2=h2->prior,*p3;

while(p1!

=h1&&p2!

=h2)//每个链表元素相加

{

i=p1->data+p2->data;

p1=p1->prior;

p2=p2->prior;

InsertNode(head3,j++,i);

}

while(p1!

=h1)

{

InsertNode(head3,j++,p1->data);

p1=p1->prior;

}

p3=head3->next;

while(p3!

=head3->prior)//处理链表元素

{

if(p3->data>=10000)

{

p3->next->data+=p3->data/10000;

p3->data%=10000;

}

if(p3->data<0)//处理负数

{

if(head3->prior!

=0)

{

p3->next->data-=1;

p3->data+=10000;

}

p3->data=(int)fabs(p3->data);

}

p3=p3->next;

}

if(head3->prior->data>=10000)//处理最前面的数

{

InsertNode(head3,j,head3->prior->data/10000);

head3->prior->prior->data%=10000;

}

if(head3->prior->data<=-10000)

{

InsertNode(head3,j,head3->prior->data/10000);

head3->prior->prior->data%=10000;

head3->prior->prior->data=(int)fabs(head3->prior->prior->data);

}

PrintNode(head3);

}

 

8.两数相减

voidjian(DLNode*h1,DLNode*h2)

{

inti=0,j=0;

DLNode*head4;

InitNode(&head4);

DLNode*p1=h1->prior,*p2=h2->prior,*p4;

while(p1!

=h1&&p2!

=h2)//每个链表元素相减

{

i=p1->data-p2->data;

p1=p1->prior;

p2=p2->prior;

InsertNode(head4,j++,i);

}

while(p1!

=h1)

{

InsertNode(head4,j++,p1->data);

p1=p1->prior;

}

p4=head4->next;

while(p4!

=head4->prior)//处理链表元素

{

if(p4->data>=10000)

{

p4->next->data+=p4->data/10000;

p4->data%=10000;

}

if(p4->data<0)//处理负数

{

if(head4->prior!

=0&&p4->data<=-10000)

{

p4->next->data-=1;

p4->data+=10000;

}

p4->data=(int)fabs(p4->data);

}

p4=p4->next;

}

if(head4->prior->data>=10000)//处理最前面的数

{

InsertNode(head4,j,head4->prior->data/10000);

head4->prior->prior->data%=10000;

}

if(head4->prior->data<=-10000)

{

InsertNode(head4,j,head4->prior->data/10000);

head4->prior->prior->data%=10000;

head4->prior->prior->data=(int)fabs(head4->prior->prior->data);

}

PrintNode(head4);

}

 

4.主函数的程序流程图

 

四、调试分析

1.实际完成的情况说明

程序基本功已完成,包括:

输入长整型数字字符,用双向循环链表储存,计算两数之和、之差,输出值,删除链表,基本符合题目要求。

2.程序的性能分析

时间复杂度:

O(strlen(data1)+strlen(data2))

3.上机过程中出现的问题及其解决方案

1)双向循环链表指针指向错误

双向循环链表使用错误,指针顺序不对,参考教课书改正。

2)打印顺序错误

由于计算值储存顺序是从尾到头,开始误认为是从头到尾,修改指针指向改正。

3)中间计算值错误

中间计算值不足四位的应用0补足。

4)中间值小于0处理错误

中间值小于0但大于-100000的数应取绝对值,小于-10000的数应先借位,这个数加上10000后,再取绝对值

4.程序中可以改进的地方说明

两操作数的头指针存于指针数组中是简化程序结构的一种方法,但由于广泛使用指针易造成混乱,所以就放弃了,以后可以改进。

5.程序中可以扩充的功能及设计实现假想。

本程序可拓展到乘除运算,还有乘方和阶乘运算。

五、测试结果

●测试方法:

输入数据

●测试数据:

(1)0;0;加法应输出“0”,减法应输出”0”。

(2)-2345,6789;-7654,3211;加法应输出“-1,0000,0000”,减法应输出”5408,6422”。

(3)-9999,9999;1,0000,0000,0000;加法应输出“9999,0000,0001”,减法应输出1,0000,9999,9999。

(4)1,0001,0001;-1,0001,0001;加法应输出“0”,减法应输出”2,0002,0002”。

(5)1,0001,0001;-1,0001,0000;加法应输出“1”,减法应输出”2,0002,0001”。

(6)-9999,9999,9999;-9999,9999,9999;加法应输出“1,9999,9999,9998”,减法应输出”0”。

(7)1,0000,9999,9999;1;加法应输出“1,0001,0000,0000”,减法应输出”1,0000,9999,9998”。

六、用户手册

本程序使用起来简单方便,只要按照菜单提示进行即可。

1.加法

1.输入0;0;

2.输入-2345,6789;-7654,3211;

3.输入-9999,9999;1,0000,0000,0000;

4.输入1,0001,0001;-1,0001,0001;

5.输入1,0001,0001;-1,0001,0000;

6.输入-9999,9999,9999;-9999,9999,9999;

7.输入1,0000,9999,9999;1;

 

2.减法

1.输入0;0;

2.输入-2345,6789;-7654,3211;

3.输入-9999,9999;1,0000,0000,0000;

4.输入1,0001,0001;-1,0001,0001;

5.输入1,0001,0001;-1,0001,0000;

6.输入-9999,9999,9999;-9999,9999,9999;

7.输入1,0000,9999,9999;1;

8.输入0;0;后输入0退出

 

七、体会与自我评价

通过这次的课程设计,我进一步加深了对数据结构的理解。

这次课程设计我抽到的题目是长整数四则运算,长整数四则运算的功能比较单一,即输入两个长整数(数字字符和“,”和“;”),每四个数字字符通过atoi()函数转换成数字后储存在一个节点里,每两个对应的节点相加、相减后,生成一个新的节点来储存,然后对链表进行处理,可采用双向循环链表实现长整数的存储,主要原因是顺序表操作起来比较简单,算法较易理解,然后打印链表,最后删除链表,销毁头结点。

这次的课程设计我采用的是C语言编程语言,在编程过程中也遇到了很多问题,但经过努力调试修改,基本实现了长整数加法的基本功能。

通过这次课程设计我回顾了以前所学的编程知识,理解了学习完数据结构后的编程与以前编程方法上的不同。

在以往的编程方法上,我们习惯于是用数组和顺序的储存结构进行编程,这种方法在进行插入和删除是及为复杂不易实现。

但数据结构给我们提供了更多的不同的而且较为简单的编程方法,如链表,而且通过这次课程设计,我认识到了链表的许多优点。

通过这次编程我还学习到了一些新的知识,现如下总结:

1)把字符串转换成整型数函数:

atoi()函数,它包含在头文件:

#include中。

2)双向循环链表的使用,使我对链表的储存结构有了全新的认识

3)再进行数据处理时应仔细分析

4)应仔细分析运算法则

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

当前位置:首页 > 高中教育 > 理化生

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

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