数据结构实验--大数运算之计算n的阶乘 (n≥20)
一、问题描述
大数运算——计算n的阶乘 (n≥20)。
【基本要求】
- (1)数据的表示和存储:
①累积运算的中间结果和最终的计算结果的数据类型要求是整型——这是问题本身的要求。
②试设计合适的存储结构,要求每个元素或结点最多存储数据的3位数值。 - (2)数据的操作及其实现:基于设计的存储结构实现乘法操作,要求从键盘上输入n值;在屏幕上显示最终计算结果。【测试数据】
(1)n=20,n!=2432902008176640000
(2)n=30,n!=265252859812191058636308480000000,
【实现提示】
- (1)设计数据的存储结构:
介于阶乘运算的精确性以及实型数据表示的不精确性,本题不能采用实型表示累积运算的中间结果和最终的计算结果,而只能用整型。然而由于普通整型和长整型所能表述数的范围受其字长的限制,不能表示大数阶乘的累积结果,故必须设计一个合适的数据结构实现对数据的存储,例如可以让每个元素或结点存储数据的若干位数值。从问题描述不难看出n值为任意值,故为使程序尽量不受限制,应采用动态存储结构。 - (2)实现两个数的乘法运算需考虑:乘数的各位数都要与被乘数进行乘法运算;乘法过程中的进位问题及其实现。因每个元素或结点最多存储数据的3位数值,故当元素或结点中的数值大于999,需向前一个元素或结点进位。
二、需求分析
计算阶乘时如果直接用一个整形来存结果则容易发生溢出(由题目所给的测试数据易得,30的阶乘就已经高达三十多位),所以就有必要设计一种存储结构来存阶乘得到的值,由学过的知识容易想到可以利用链表来存储,链表的每一个节点内存储特定的几位数,由于链表是可以无限延长的 所以链表能存储的数的位数也是无限长的。
所以现在我们设计一个程序,由用户输入其需要计算的阶乘的数字,程序计算出的阶乘的结果对应的呈现在屏幕上。
三、设计
3.1 整体设计
用struct设计节点类方便访问,再设计链表类定义数据成员和构造函数并声明打印函数和阶乘函数为其友元函数,定义阶乘函数和打印函数用来计算阶乘
3.2 详细设计
- 节点类:用struct设计节点类,设计数据域data和指针域link,设计两个构造函数,一个无参构造函数初始指针域为NULL,一个含一个变量a的构造函数初始指针域为NULL数据域为a。
链表类:设计一个数据成员为节点类类型的指针,设计两个构造函数 - 阶乘函数:
i从一到二十逐步加一,C指针指向链表头节点,进位表示为Out
如果C指针不为空则循环以下语句
节点新的值=旧的值*i + 进位
进位=当前节点值/1000 (高位的1代表低位的1000)
当前值对1000取余(保证只存三位数,剩下的值由Out传给高位)
在当前节点处理完后 判断是否需要增加节点
(进位不为零且后继为空则创建一个后继节点)
C指针向后指一位 - 打印函数:
如果当前指针指向节点的指针域为空,则打印此节点的数据
否则1,打印后继节点 2,输出当前节点数据(位宽为三,空位补0)
四、测试数据及测试结果:
测试输入:-5,20,30,1000
测试目的:设计该输入的目的在于测试程序在哪方面可能存在漏洞;
4.1:-5的计算
正确输出:输入有误,请重新输入一个自然数
实际输出:输入有误,请重新输入一个自然数
4.2: 0的计算
正确输出:1
实际输出:1
4.3:20的计算
正确输出:2432902008176640000
实际输出:2432902008176640000
4.4:30的计算
正确输出:265252859812191058636308480000000
实际输出:265252859812191058636308480000000
4.5:1000的计算
输出结果较长,此处省略
且经对比实际输出=正确输出