天天看点

阶乘计算升级版

4-10 阶乘计算升级版   (20分)

本题要求实现一个打印非负整数阶乘的函数。

函数接口定义:

void Print_Factorial ( const int N );
           

其中

N

是用户传入的参数,其值不超过1000。如果

N

是非负整数,则该函数必须在一行中打印出

N

!的值,否则打印“Invalid input”。

裁判测试程序样例:

#include <stdio.h>

void Print_Factorial ( const int N );

int main()
{
    int N;
				
    scanf("%d", &N);
    Print_Factorial(N);
    return 0;
}

/* 你的代码将被嵌在这里 */
           

输入样例:

15
           

输出样例:

1307674368000
           
解题思路:

C 语言提供的数据类型都不足以支持这么大的数据。该算法模拟了手算过程,用数组来存放最终结果的每位。由于 N 值不超过 1000,利用计算器计算了一下结果最多有 2568 位。所以本算法定义了一个 2568 位的数组来存放最终的结果。不想精确计算或者没有工具计算的话,可以直接定义一个很大的数组。

算法过程:

以计算 5 的阶乘为例,假设现在数组里已经存放了计算好的 4 的阶乘结果          2 4              (fact[1] = 2, fact[0] = 4)                ,接下来要乘以 5。算法过程即为,4 * 5 加上进数 n(初始时 n 为 0),用 temp 保存这个值。temp 取余后放在 fact[0] 中。temp 再除以 10,得到进数 n,然后处理下一位。下一位操作当前位的操作是一致的。就这样一致循环处理下去,直到没有进位。

本质上是模拟手算的过程。

最后逆序输出结果数组。

解题代码:
       
void Print_Factorial ( const int N) {
    int fact[] = {};
    fact[] = ;
    int n = , k = ; // n 为进的数,k 为当前结果的总位数 
    for (int i=; i<=N; i++) {
        for (int j=; j<k; j++) {
            int temp = i * fact[j] + n;
            fact[j] = temp  % ;
            n = temp / ; 
            if (n && j==k) {
                k++;  
            } // 当有进位且已经处理到最前位时才开拓目标数组的下一位 
        }
    } 
    for (int i=k; i>=; i--) {
        if (N >= ) {
            printf("%d", fact[i]);
        } else {
            printf("Invalid input");
        }
    }
    printf("\n");
}
           

继续阅读