鱼C论坛

 找回密码
 立即注册
查看: 3609|回复: 8

c语言阶乘

[复制链接]
发表于 2022-4-16 23:08:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
有没有大佬会写呢,以及快掉没头发了
CJDTX{AF_A0$(482W%YMHNH.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-4-16 23:31:23 | 显示全部楼层
2个for就可以了
#include <stdio.h>

int factorial(int n)
{
        int i, product;

        product = 1;
        for(i=n; i>0; i--)
        {
                product *= i;
        }
        return product;
}

int main(void)
{
        int i, n, sum;
        
        printf("请输入:");
        scanf("%d", &n);

        sum = 0;
        for(i=n; i>0; i--)
        {
                sum += factorial(i);
        }
        
        printf("结果:%d\n", sum);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-17 07:22:21 | 显示全部楼层
本帖最后由 jhq999 于 2022-4-17 08:35 编辑
ba21 发表于 2022-4-16 23:31
2个for就可以了


n<=50,高精度,unsigned long long 也不够
可以利用乘法和加法的竖算式,把数分段储存,分段乘积
举个简单的里子
4567*25
char a1[4]={4,5,6,7},a2[2]={2,5},a3[6]={0};
a3=a1*a2[1]={0,0,20,25,30,35}//进位={0,2,(20+2)%10=2,(25+3)%10=8,(30+35/10)%10=3,35%10=5}={0,2,2,8,3,5}
a3=a1*a2[0]+a3={0,8,10,12,14,0}+{0,2,2,8,3,5}//进位={0,9,1.3,4,0}+{0,2,2,8,3,5}={0,9+2,1+2,3+8,4+3,0+5}={0,11,3,11,7,5}//进位={1,1,4,1,7,5}
我是用每个字节存10进制,好理解点,你也可以用int存10000进制,道理都是一样的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-17 09:39:30 | 显示全部楼层
本帖最后由 傻眼貓咪 于 2022-4-17 09:42 编辑

题目写明 n <= 50 啊,根本超出储存范围了,确实唯一方法就如楼上大佬说的那样,分段计算了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-17 11:10:59 | 显示全部楼层
ba21 发表于 2022-4-16 23:31
2个for就可以了

这个算不了50那么大的呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-17 11:12:43 | 显示全部楼层

分段计算要怎么实现啊,我有点看不懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-17 11:33:04 | 显示全部楼层
Boring1031 发表于 2022-4-17 11:12
分段计算要怎么实现啊,我有点看不懂

给你基础代码参考吧,因为真正题解太长,所以有点懒得写:
#include <stdio.h>
#define N 5

// 乘法
void mul(int* A, int* B) {
        int C[N << 1] = { 0 };
        for (int b = N - 1; b > 0; b--) {
                for (int a = N - 1; a > 0; a--) {
                        C[a + b] += ((A[a] * B[b]) + C[b]) % 10;
                        C[a + b - 1] += ((A[a] * B[b]) + C[b]) / 10;
                }
        }
        for (int i = N - 1, j = 0; j < N; i++, j++) A[j] = C[i];
}

// 打印
void show(int* A) {
        int flag = 0;
        for (int i = 0; i < N; i++) {
                if (A[i]) flag = 1;
                if (flag) printf("%d", A[i]);
        }
}

int main() {
        int
                A[N] = { 0, 0, 3, 5, 4 }, // A = 354
                B[N] = { 0, 0, 0, 2, 4 }; // B = 24

        mul(A, B); // A = A*B
        show(A); // A = 8496

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-17 13:38:47 | 显示全部楼层
本帖最后由 ba21 于 2022-4-17 13:43 编辑
Boring1031 发表于 2022-4-17 11:10
这个算不了50那么大的呀


没注意。
原理差不多。搞2个大数相加,相乘函数就解决了。
代码没有处理内存释放。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int Max(int a,int b)
{
        return a > b ? a : b;
}

// 大数相加
char* AddBigNumber(char *s, char *p)
{
        int x = 0;
        int len1 = strlen(s);         /*  获得字符串长度  */
        int len2 = strlen(p);
        int len3 = Max(len1--, len2--) + 1;      /*  结果的长度最大应为较长字符串长度+1  */
        char *arr;
        arr = (char*)malloc(sizeof(char)*(len3+1));
      /*  为结果申请存储空间,+1是因为末尾有一个'\0'  */
        arr = &arr[len3];       /*  因为是从末尾开始相加,所以指针跳转到末尾  */
        *arr = '\0';
        while(len1 >= 0 || len2 >= 0)  /*  当两个字符串都走完了才结束  */
        {
                if(len1 >= 0)
                        x += s[len1--] - '0';
                if(len2 >= 0)
                        x += p[len2--] - '0';
                *(--arr) = (x % 10) + '0';       /*  将结果对10取余赋给arr  */
                x /= 10;              /*  重置为上一次运算的进位  */
        }
        if(x == 1)           /*  如果循环完后还有进位  */
                *(--arr) = '1';
        return arr;
}

// 大数相乘
char *MultipyBigNumber(char *s, char *p)
{
    int i, j, x, bit1, bit2;
    int len1 = strlen(s);
    int len2 = strlen(p);
    int len3 = len1 + len2; /* 结果的位数最大应为两个长度相加 */

    char *arr;
    arr = (char*)malloc(sizeof(char)*(len3+1));

    arr[len3] = '\0';

    arr = &arr[len3];
    len1--;
    len2--;
    i = x = 0;

    while(i < len3 - 1 || x != 0)
    {
        for(j = 0; j <= i; j++)
        {
            bit1 = len1 - i + j; /* 第一个数从当前最高位开始递减到个位 */
            bit2 = len2 - j; /* 第二个数从个位到当前最高位 */
            if(bit1 >= 0 && bit2 >= 0) /* 当两个位数都有效才相乘,防止出现位数不相称情况 */
                x += (s[bit1] - '0') * (p[bit2] - '0');
        }

        *(--arr) = x % 10 + '0';
        x /= 10;
        i++;
    }

    if(*arr++ == '0') /* 如果结果为0,只返回一个0即可,不用返回n个0 */
        *arr = '\0';

    return --arr;
}

char *factorial(int n)
{
    int i;
    char *product;
    char buf[1024];

    product=NULL;
    for(i=n; i>0; i--)
    {
        if(product==NULL)
        {
            product = MultipyBigNumber("1", itoa(i, buf, 10));
            continue;
        }
        product = MultipyBigNumber(product, itoa(i, buf, 10));
    }

    return product;
}

int main(void)
{
    int i, n;
    char buf[1024];
    char *sum;

    printf("请输入:");
    scanf("%d", &n);

    sum=NULL;
    for(i=n; i>0; i--)
    {
        if(sum==NULL)
        {
            sum = AddBigNumber("0", factorial(i));
            continue;
        }
        sum = AddBigNumber(sum, factorial(i));
    }

    printf("结果%s\n", sum);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-17 22:18:24 | 显示全部楼层
#include <stdio.h>

int main()
{
    int m = 1, n, i, j, sum = 0;
    printf("请输入需要计算的阶乘最大数: ");
    scanf("%d", &n);
    //外层循环,控制加法
    for (i = 1; i <= n; i++)
    {
        //内存循环,控制每个数的阶乘
        for (j = 1; j <= i; j++)
        {
            m *= j;
        }
        //阶乘相加
        sum += m;
        m = 1;   //将每个数阶乘算好后,对基数做初始化
    }
    printf("sum = %d", sum);
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-5 18:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表