数学总结之关于阶乘的几种问题

本文探讨了阶乘计算的两个主要方面:高精度计算和数论相关问题。针对高精度计算,文章给出了递归和迭代的解决方案,并详细解释了高精度乘法算法。在数论部分,文章列举了几种与阶乘相关的数论问题,如求阶乘末尾第一个非0数字、阶乘末尾0的数量以及阶乘的位数等,并提供了相应的求解思路和方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有关阶乘的算法,不外乎两个方面:一是高精度计算;二是与数论相关。                                                    

一. 高精度计算阶乘

这实际上是最没有技术含量的问题,但是又会经常用到,所以还是得编写,优化它的计算。
首先看小于等于12的阶乘计算(计算结果不会超出32位范围):

        int factorial(int n)

        {

           if (n == 1 || n == 0) return 1;
           return factorial(n-1)*n;
        }

    这个递归程序简单明了,非常直观,然而一旦n > 12,则超过32位int型的范围出现错误结果,所以上面这个递归程序仅适合n <= 12的阶乘计算,为了计算较大n的阶乘,需要将高精度乘法算法纳入到阶乘计算中来,高精度乘法过程可以如下简单的描述:(其中A * B = C,A[0], B[0], C[0]分别存储长度)

    for (i = 1; i <= A[0]; i++)

    for (j = 1; j <= B[0]; j++) {

        C[i+j-1] += A[i]*B[j];          // 当前i+j-1位对应项 + A[i] * B[j]
        C[i+j] += C[i+j-1]/10;         // 它的后一位 + 它的商(进位)
        C[i+j-1] %= 10;                  // 它再取余即可

    } 

    C[0] = A[0] + B[0];   
    while (C[0] > 1 && C[C[0]] == 0) C[0]--;   // 去头0,获得实际C的长度

有了这个高精度乘法之后,计算阶乘就可以简单的迭代进行:
    for (i = 2; i <= n; i++) {
          将i转换成字符数组;
          执行高精度乘法:将上一次结果乘上i

    }

 二. 与数论有关

       由于阶乘到后面越来越大,巧妙的利用数论求得一些有趣的数字(数值)等成为阶乘算法的设计点,下面给出几道相关的问题与分析:

       (1)   计算阶乘末尾第一个非0数字:

        例1.阶乘的最后一个不为0的数 蓝桥杯

       题目描述: 一个整数n的阶乘可以写成n!,它表示从1到n这n个整数的乘积。阶乘的增长速度非常快,例如,13!就已经比较大了,已经无法存放在一个整型变量 中;而35!就更大了,它已经无法存放在一个浮点型变量中。因此,当n比较大时,去计算n!是非常困难的。幸运的是,在本题中,我们的任务不是去计算 n!,而是去计算n!最右边的那个非0的数字是多少。例如,5! = 12345 = 120,因此5!最右边的那个非0的数字是2。再如:7! = 5040,因此7!最右边的那个非0的数字是4。请编写一个程序,输入一个整数n(n<=100),然后输出n! 最右边的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值