Мой код для вычисления в факториале (с использованием рекурсии) работает до 24, но показывает неправильные ответы после этого в c. пожалуйста, проверьте - PullRequest
0 голосов
/ 22 марта 2020
#include <stdio.h>
int main()
{
    int n, t, rem, i, j, k;
    scanf("%d", &t);
    int ans[t], integer[1000];
    for(i=0; i<t; i++)
    {
        int count=0;
        scanf("%d", &n);
        for(j=0; j<1000; j++)
        {
            integer[j]=0;
        }
        for(j=0, k=n; k>0; k/=10, j++)
        {
            integer[j]=k%10;
            count++;
        }
        factorial(n, count, integer);
    }
    return 0;
}
void factorial(int n, int count, int* integer)
{
    int i, j, k, rem=0, temp;
    if(n==1)
    {
        for(i=count-1; i>=0; i--)
        {
            printf("%d", integer[i]);
        }
        printf("\n");
        return;
    }
    else
    {
        for(i=0; i<count; i++)
        {
            temp=integer[i]*(n-1);
            integer[i]=(temp%10)+rem;
            rem=temp/10;
            if(i==count-1)
               {
                    if(rem!=0)
                    {
                        for(j=0, k=rem; k>0; k/=10, j++)
                        {
                        integer[count]=k%10;
                        count++;
                        }
                        break;
                    }
               }
        }
        factorial(n-1, count, integer);
    }

}

Объяснение: Я сохраняю числа в обратном порядке, например, на входе: 100 целых чисел, сохраненных в массиве: 0 0 1 0 0 0 0 0 ... тогда при вызове факториальной функции n = 100, count = 3 и целочисленный массив в качестве входных данных. мы умножаем первый элемент массива на n-1 и переносим остаток ... это продолжается до тех пор, пока весь целочисленный массив не умножается на 99, затем мы снова вызываем факториал, умножая массив на 98 и так далее, пока не достигнем 1, где мы в конечном итоге печатаем ответ.

Проблема: код дает правильный результат только до 24 и дает неправильный вывод после этого.

Ответы [ 2 ]

1 голос
/ 22 марта 2020

вы полагаете, что каждый элемент в integer находится между 0 и 9, но это не так, добавление пробела после записи di git указывает на проблему, например вычисление факта от 1 до 22 :

1 
2 
6 
2 4 
1 2 0 
7 2 0 
5 0 4 0 
4 0 3 2 0 
3 6 2 8 8 0 
3 6 2 8 8 0 0 
3 9 9 1 6 8 0 0 
4 7 8 10 0 1 6 0 0 <<< wrong value for !12
6 2 2 7 0 2 0 8 0 0 
8 7 1 7 8 2 9 1 2 0 0 
1 3 0 7 6 7 4 3 6 8 0 0 0 
2 0 9 2 2 7 8 9 8 8 8 0 0 0 
3 5 5 6 8 7 4 2 8 0 9 6 0 0 0 
6 4 0 2 3 7 3 7 0 5 7 2 8 0 0 0 
1 2 1 6 4 5 0 10 0 4 0 8 8 3 2 0 0 0  <<< wrong value for 19
2 4 3 2 9 0 2 0 0 8 1 7 6 6 4 0 0 0 0 
5 1 0 9 0 9 4 2 1 7 1 7 0 9 4 4 0 0 0 0 
1 1 2 3 10 0 0 7 2 7 7 7 7 6 0 7 6 8 0 0 0 0 <<< wrong value for 22

Таким образом, ваша проблема возникает из-за того, что вы недостаточно справляетесь с переносом

Пример 4 4 * 8 10 0 1 6 0 0 в правильном порядке производит 4 7 9 0 0 1 6 0 0 как ожидалось

Чтобы решить это в factorial после строки

rem=temp/10;

add

if (integer[i] > 9)
{
    rem += integer[i] / 10;
    integer[i] %= 10;
}

Из этого:

  • ans [t] бесполезно
  • при использовании scanf или эквивалентная функция проверяет результат, чтобы убедиться, что верное значение было введено
  • , если в результате используется более 1000 di git в основание 10, вы выведите из integer
0 голосов
/ 23 марта 2020

вычисление переполняет возможность целого числа.

...