长整数加减运算实验报告(共29页).doc
《长整数加减运算实验报告(共29页).doc》由会员分享,可在线阅读,更多相关《长整数加减运算实验报告(共29页).doc(29页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上实验一一、需求分析实验内容:计算机存储的数据是有范围限制的,对于超出存储限制的数据无法直接在计算机中计算,为此需要设计相应的程序来完成这种超出范围限制的长整数间的四则运算。设计一个实现任意长的整形数进行四则运算 的程序,要求完成长整数的加、减运算,乘除运算可选做。在这里长整数没有范围限制,可任意长。运算后的进位、借位等都要进行正确处理,可实现动态的输入,实时的输出。实验目的:学习使用基本的数据结构解决实际应用中的问题,将学习的理论知识应用于实践,增强学生解决实际问题的能力。这里可采用的基本数据结构为线性表。测试数据:1) 输入:动态输入以数字开头,可以任意长度,中间不
2、用输入分隔符,直接输入即可。 2) 输出:实时输出的结果是加减运算后的结果。3) 功能:实现长整数的加减运算。4) 测试数据:0、0; 输出“0” 2345,6789、-7654,3211; 输出“1,0000,0000” 1,0000,0000,0000、9999,9999; 输出“9999,0000,0001” 1,0001,0001、;1,0001,0001; 输出“0”二、 概要设计1. 数据结构此实验采用的数据结构是双向循环链表。这样可以很容易的找到他的前驱以及它的后继。节点采用结构体类型,代码如下:typedef struct Node / 双向链表的结构体定义 int data;
3、 struct Node *prior;struct Node *next;DLNode;2. 使用函数1) void ListInitiate(DLNode *head)操作结果:初始化一个头结点为head的双向循环链表;2) int ListLength(DLNode *head)操作结果:计算以head为头结点的链表的长度3) int ListInsert(DLNode *head,int i,int x)操作结果:将节点数据为x的节点插到第i个位置上去。4) int abs(int x)操作结果:绝对值函数,返回x的绝对值。5) int InputNumber(DLNode *head
4、)操作结果:将从键盘中接收数据并把得到的数据存入以head为头结点的链表中。四位一存,中间以逗号区分,结束符为分号。6) void OutputNumber(DLNode *head,int sign)操作结果:将以head为头结点的链表中的所有数据输出到显示屏上,7) void add(DLNode *head1,DLNode *head2,DLNode *head3)操作结果:实现正数加正数的加法操作。8) int change(DLNode *head1,DLNode *head2)操作结果:判断存在俩个链表中的数的大小,如何head1中的数大于head2中的数那么返回值为0,反之返回值
5、为1,相等时返回值为2;9) void method(DLNode *head1,DLNode *head2,int x)操作结果:计算正数乘以正数的乘法运算。10) void minus(DLNode *head1,DLNode *head2,DLNode *head3)操作结果:计算正数减正数的减法运算。11) void yunsuan(DLNode *head1,DLNode *head2,DLNode *head3,char ch)操作结果:正数,负数,加法,减法。计算式共分为八种运算,在这之前我已经实现了二种运算,那么这个函数就是把这八种运算按照一定的规则转化成已经实现的二种运算来实
6、现完整的加减法运算。12) void chengfa(DLNode *head1,DLNode *head2)操作结果:在乘法中我只是实现了正数乘以正数的运算,那么这个函数就是通过调用method函数按照一定的规则来实现完整的乘法运算。13) void main()操作结果:主函数。调用以上的各个函数来引导用户进行长整数的加法运算,加法运算,乘法运算。三、 详细设计1. 数据结构详细设计typedef struct Node / 双向链表的结构体定义int data;struct Node *prior;struct Node *next;DLNode;双向循环链表的节点由三个部分组成,第一是
7、数据部分data存储此节点的数据,第二是此节点的前驱指针部分*prior指向此节点的前驱,第三是此节点的后继指针部分*next指向此节点的后继。数据部分我们约定它为整形变量,前驱后继指针均为结构体Node类型。2. 链表初始化函数:void ListInitiate(DLNode *head) /双向链表的初始化if(*head=(DLNode *)malloc(sizeof(DLNode)=NULL) exit(0);(*head)-prior=*head;(*head)-next=*head;初始化之前需要定义一个类型为Node型的头结点变量,经过函数后完成链表的初始化即:头节点的前驱指针
8、指向自己,同时他的后继指针也指向自己。3. 计算已知的链表长度:int ListLength(DLNode *head) /双向链表的表长DLNode *p=head;int size=0;while(p-next!=head) p=p-next; size+;return size; 此函数计算的是已知链表的长度。主要思想:从头结点开始寻找下一个节点,找到计数器加一。直到再次寻找到头结点时停止,计算完毕。4. 插入函数:int ListInsert(DLNode *head,int i,int x) /双向链表的数据插入,i表示是插入的第几个元素DLNode *p,*s;int j;p=he
9、ad-next;j=0;while(p!=head&jnext;j+;if(j!=i) printf(n插入位置不合法!);return 0;if(s=(DLNode *)malloc(sizeof(DLNode)=NULL) exit(0);s-data=x;s-prior=p-prior;/插入p-prior-next=s;s-next=p;p-prior=s;return 1;此函数是已知一双向链表实现在第i个位置插入data为x的节点。函数需要注意的是在什么位置插入才是合法的,在就是在该节点指针时的顺序不要搞错。5. 绝对值函数:int abs(int x) if(x0) return
10、 -x;else return x;此函数是实现求一个整数的绝对值。设计这么一个函数主要是考虑到在存储负数的时候头结点应该变为正整数,然后通过其他手段变相实现那种运算。6. 读入数据并插入对应的链表函数:int InputNumber(DLNode *head) /读入输入的数据int input,i=0;/第i个节点char c;scanf(%d%c,&input,&c);while(1)if(inputdata=0;/将长整数的符号保存在头结点中/input=abs(input);/取输入数字的绝对值ListInsert(head,i,input);/插入数据else if(input=0
11、&i=0)/输入数为正且是第一个节点head-data=1;/将长整数的符号保存在头结点中ListInsert(head,i,input);/插入数据else if(head-next-data=0)ListInsert(head,i,input);/非第一个节点else/input=-1*input;ListInsert(head,i,input);i+;if(c=;) break;/遇到数据输入完成标志,跳出循环scanf(%d%c,&input,&c);return 1;此函数实现的是从键盘上得到数据根据三种情况进行不同的处理,判断是否是头结点,判断是否是整数,判断输入的字符是否是“;”
12、分号。并且如果是正整数它的头结点data等于1否则为0。7. 输出函数void OutputNumber(DLNode *head,int sign) /从表尾输出数据元素DLNode *r=head-next;while(r-data=0&r!=head-prior)r=r-next;if(sign=1) printf(结果是:);elseprintf(结果是: -);printf(%d,r-data);r=r-next;while(r!=head)if(r-datadata);else if(r-datadata);else if(r-datadata);elseprintf(,%d,r-
13、data);r=r-next;printf(n);此函数实现的是将最后的结果输出到显示屏上,经过判断数据的正负和数据的范围来进行不同的处理,以保证在显示屏上显示的是正确的格式。8. 不完整加法函数(只可实现正数加上正数)void add(DLNode *head1,DLNode *head2,DLNode *head3) int z=0;int e;DLNode *p1,*p2; p1=head1-prior; p2=head2-prior; while(p1!=head1&p2!=head2) e=p1-data+p2-data+z;if(e=10000)z=1;e=e%10000;else
14、 z=0;ListInsert(head3,0,e);p1=p1-prior;p2=p2-prior; if(p1=head1&p2!=head2) while(p2!=head2) e=p2-data+z;if(e=10000)z=1;e=e%10000;else z=0;ListInsert(head3,0,e);p2=p2-prior; if(z=1) ListInsert(head3,0,z); else if(p1!=head1&p2=head2) while(p1!=head1) e=p1-data+z;if(e=10000)z=1;e=e%10000; else z=0; Lis
15、tInsert(head3,0,e); p1=p1-prior; if(z=1) ListInsert(head3,0,z); else if(z=1) ListInsert(head3,0,z); 此函数实现的是两个正数之间的相加运算,主要的算法和我们手算加法是一样的,首先设置一个进位计数的变量,根据存储的特点从低位开始相加带上进位即可得出相应的位和,最后更新进位变量。处理边界状况:如果两个链表一样长同时他们最高位在计算完成时仍然会有进位,那么应该考虑到在数据的更高位插入一个1表示最后的计算结果,这样才可以保证数据的完整性。9. 判断俩正数大小函数:int change(DLNode *he
16、ad1,DLNode *head2)int length1,length2,r=2;length1=ListLength(head1); length2=ListLength(head2);DLNode *p1,*p2;p1=head1-next;p2=head2-next;if(length1length2)r=0;return r;else if(length1length2)r=1;return r;elseint i=0;for(i=0;idatap2-data)r=0;return r;break;else if(p2-datap1-data)r=1;return r;break;e
17、lsep1=p1-next;p2=p2-next;r=2;return r;此函数实现的是判断俩个正数的大小。考虑俩正数的在链表中所占存储单元的多少,多的一定大,当他们一样长时,一位一位的比较直到找到一个节点中的data比另一个链表的对应节点的data大为止。如果最后仍是一样大那么这两个数就是一样大的。返回值为自己约定的参数r等于2表示俩数一样大,等于1表示第二个数大,等于 0表示第一个数大。10. 乘法函数:void method(DLNode *head1,DLNode *head2,int x)void minus(DLNode *head1,DLNode *head2,DLNode *
18、head3);DLNode *temp1;DLNode *temp2;DLNode *temp3;DLNode *temp4;DLNode *temp5;int e,z=0,i,j;ListInitiate(&temp1);ListInitiate(&temp2);ListInitiate(&temp3);ListInsert(temp2,0,0);DLNode *p1,*p2;p1=head1-prior;p2=head2-prior;for(i=0;idata*p2-data+z;if(e9999)z=e/10000;e=e-z*10000;else z=0;ListInsert(temp
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 整数 加减 运算 实验 报告 29
限制150内