经验技巧6-2 大数阶乘优化算法.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
经验技巧6-2 大数阶乘优化算法 【例6-6】给出了大数阶乘的算法,该算法使用数组存放阶乘的结果,每一个数组元素存放结果的一位。计算十万的阶乘需要近260秒的时间,实际上只要程序中的N足够大,还可以求更大数的阶乘,但程序执行的时间会更长,可能要几个小时,甚至更长,因此需要考虑对算法进行优化。 int型数组的每一个元素可以存放的最大整数为2147483647,是一个十位数,而算法中每一个元素只存放结果的一位,显然太浪费了。 由于算法中需要计算自然数n与数组元素值的乘积加上前一位的进位,所以每个数组元素的位数不能太多,否则将超过最大整数2147483647而导致溢出,如果每个数组元素存放4位数,大约可计算到二十万的阶乘,确保结果是精确的,如果再使用无符号基本整型,大约可计算到四十万的阶乘,确保结果是精确的。 由此,定义符号常量M的值为10000作为模数,符号常量B的值为4表示数组元素存放的最多位数,符号常量N的值为600000表示n!结果位数的B分之一,存放n!结果的数组bit定义为静态无符号基本整型。 计算i!时将原来的用10除处理进位和余数改为用M除。 由于除存放最高位的元素外,每个元素都存放B位,而存放最高位的元素可能不足B位,输出前需先统计存放最高位元素bit[k]的位数,另外,低位的0(只能输出一个0)和不足B位的应使用B个输出域宽,不足的用0补足,才能保证其它各位均输出B位。 其它说明详见程序代码中的注释。 优化的程序代码: (1) #include stdio.h (2) #define M 10000//M与n的乘积不能超过4294967295 (3) #define B 4//数组元素存放的最多位数 (4) #define N 600000 //n!的位数,要足够大 (5) int fact(int bit[],int n) (6) { (7) int i,j,k=N-1,carry;//k表示第一个非0元素的下标 (8) bit[k]=1; (9) for(i=2;i=n;i++) (10) { (11) carry=0;//carry表示进位数,开始进位数为0 (12) for(j=N-1;j=k;j--) (13) { (14) bit[j]=bit[j]*i+carry; (15) carry=bit[j]/M;//处理进位 (16) bit[j]=bit[j]%M; (17) if(j==kcarry)//当处理到(i-1)!的最高位元素时(即j==k),只要有进位(即carry!=0),最高位元素下标前移 (18) k--; (19) } (20) } (21) return k; (22) } (23) int main() (24) { (25) static unsigned bit[N]={0}; //存放n!的结果 (26) int i,j=0,k,n; (27) printf(请输入一个不超过四十万的自然数,计算它的阶乘:); (28) scanf(%d,n); (29) k=fact(bit,n); (30) for(i=bit[k];i;i=i/10)//统计存放最高位元素的位数 (31) j++; (32) printf(%d!=%d,n,bit[k]);//输出最高位元素的值 (33) for(i=k+1;iN;i++) (34) printf(%0*d,B,bit[i]);//输出其它各位元素的值,位数均为B,低位0均输出B个0 (35) printf(\n); (36) printf(%d!是一个%d位数\n,n,j+(N-k-1)*B); (37) return 0; (38) } 优化后的程序计算十万的阶乘只需65秒,计算四十万的阶乘需要不到19分钟。

文档评论(0)

gayl22 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档