阶乘算法全集,阶乘末尾非零位,阶末尾零的个数(转)

本文介绍了阶乘算法的C++实现,包括高精度计算阶乘、计算阶乘末尾非零位、末尾零的个数以及相关数论问题的解决。文章详细讲解了阶乘算法的实现原理,并提供了代码示例。同时,文章还涵盖了基于搜索的算法,用于判断数字是否能表示为不同阶乘的和。
摘要由CSDN通过智能技术生成

//阶乘各算法的 C++ 类实现
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cmath>
using namespace std;
 
class Factorial {
    static const int MAXN = 5001;                          // 最大阶乘数,实际用不到这么大
    int *data[MAXN];                                            // 存放各个数的阶乘
    int *nonzero;                                                 // 从低位数起第一个非0数字
    int maxn;                                                       // 存放最大已经计算好的n的阶乘
    int SmallFact(int n);                                         // n <= 12的递归程序
    void TransToStr(int n, int *s);                           // 将数n倒序存入数组中
    void Multply (int* A, int* B, int* C, int totallen);   // 执行两个高精度数的乘法
public:
    Factorial();
    ~Factorial();
    void Calculate(int n);                                       // 调用计算阶乘
    int FirstNonZero(int n);                                    // 返回阶乘末尾第一个非0数字
    int CountZeros(int n);                                     // 返回阶乘末尾有多少个0
    int SecondNum(int n);                                    // 返回阶乘左边的第二个数字
    bool CanDivide(int m, int n);                            // 判断数值 m 是否可以整除 n!
    void Output(int n) const;
};
  
int Factorial::SmallFact(int n) {
    if (n == 1 || n == 0) return 1;
    return SmallFact(n-1)*n;
}   
 
void Factorial::TransToStr(int n, int *tmp) {
    int i = 1;
    while (n) {
        tmp[i++] = n%10;
        n /= 10;
    }   
    tmp[0] = i-1;
}  
 
void Factorial::Multply (int* A, int* B, int* C, int totallen)
{
    int i, j, len;   
    memset(C, 0, totallen*sizeof(int));   
    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;                                        // 它再取余即可
    }
    len = A[0] + B[0];   
    while (len > 1 && C[len] == 0 ) len--;             // 获得它的实际长度
    C[0] = len;  

 
Factorial::Factorial() {                                       // 构造函数,先把<=12的阶乘计算好
    maxn = 12; data[0] = new int [2];
    data[0][0] = 1; data[0][1] = 1;
    int i, j = 1;
    for (i = 1; i <= 12; i++) {
        data[i] = new int [12];
        j = j*i;
        TransToStr(j, data[i]);
    }   
    nonzero = new int [10*MAXN];
    nonzero[0] = 1; nonzero[1] = 1;                  // nonzero[0]存储已经计算到的n!末尾非0数
}
 
Factorial

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值