Почему мой скрипт CheckFactorial не работает?

#include <stdio.h>

int checkiffactorial();
int factorial(int n);

int number;

int main()
{
    int answer, n, i;
    printf("Enter a number: ");
    scanf("%d", &number);
    answer = checkiffactorial();
    if (answer == 1)
    {
        printf("It's a factorial");
    }
    else
    {
        printf("It's not a factorial");
    }
}


int checkiffactorial()
{
    static int whichnumber = 1;
    int currnumber;
    if (whichnumber > number)
    {
        return 0;
    }
    if(whichnumber <= number)
    {
        currnumber = factorial(whichnumber);
        if (currnumber == factorial(number))
        {
            return 1;
        }
        whichnumber++;
        checkiffactorial();
    }
}

int factorial(int n)
{
    int i;
    int fac;
    for(i=1; i<=n; ++i)
    {
        fac = fac * i;
    }
}

Почему этот код не работает? Мой код C предназначен для ввода числа и проверки, может ли это число быть факториалом.

Как например: если вы введете 6, это должно быть Да, потому что 3! = 6, но если вы введете 8, это не сработает.

Я не думаю, что это дубликат, потому что метод, который я сделал, был другим.

Пожалуйста, обратите внимание, что я не очень хорош в C, поэтому любые дополнительные советы могут быть оценены.

2 ответа

Решение

Вам нужно исправить 3 ошибки, чтобы эта программа работала.

  1. Ты сравниваешь factorial из whichnumber с factorial из number это неверно.
  currnumber = factorial(whichnumber);
            if (currnumber == factorial(number)) //<----never be true
            {
                return 1;
            }

Вы должны сравнить factorial из whichnumber с number

 currnumber = factorial(whichnumber);

        if (currnumber == number)  //<----should check whether it's same with the number 
        {
            return 1;
        }

2 Вы должны инициализировать fac переменная в factorial функция в противном случае будет принимать какое-то мусорное значение.

int fac=1; //<-----initialize this variable

3. Вы должны вернуть значение fact после расчета factorial,

  return fac; //<-----should return value

Вот модифицированный код:

#include <stdio.h>

int checkiffactorial();
int factorial(int n);

int number;

int main()
{
    int answer, n, i;
    printf("Enter a number: ");
    scanf("%d", &number);
    answer = checkiffactorial();
    if (answer == 1)
    {
        printf("It's a factorial");
    }
    else
    {
        printf("It's not a factorial");
    }
}


int checkiffactorial()
{
    static int whichnumber = 1;
    int currnumber;
    if (whichnumber > number)
    {
        return 0;
    }
    if(whichnumber <= number)
    {
        currnumber = factorial(whichnumber);

        if (currnumber == number)  //<----should check whether it's same with the number 
        {
            return 1;
        }

        whichnumber++;
        checkiffactorial();
    }

}

int factorial(int n)
{
    int i;
    int fac=1; //<-----initialize this variable
    for(i=1; i<=n; ++i)
    {
        fac = fac * i;
    }

    return fac; //<-----should return value
}

Вам было указано, что вы не возвращаете значение из своих функций и не используете неинициализированные значения. Эти ошибки легко сделать, но их также легко поймать: включите предупреждения для вашего компилятора, и они сообщат вам об этих вещах.

Ответ Suvojit говорит вам, что не так с вашей факториальной функцией. К сожалению, с вашей факториальной проверкой все в порядке:

  • Вы делаете число, вы проверяете глобальную переменную. Это действительно должен быть аргумент функции, чтобы вы могли вызывать ее так, как должны: is_factorial(n),
  • Вы делаете свой счетчик static переменная. Это похоже на глобальную переменную, но с ограничением, что она известна только в этой функции, что означает, что вы не можете изменить ее извне. Если ваша программа хочет проверить несколько номеров, второй вызов начинается там, где вы остановились ранее, что приводит к неверным результатам.
  • Конечно, это то, что вы хотите в своей реализации, потому что вы используете рекурсивный алгоритм. В этом случае это не хороший выбор; использовать петлю.
  • Ваше условие, когда останавливать итерацию (или когда прерывать цикл), сравнивает число с числом, из которого вы взяли факториал. Вы должны проверить это на самом факториале.

Обратите внимание, что типичный int имеет 32 бита и может представлять положительные значения до 2³¹. Факториал 13! уже превышает этот предел. Таким образом, вы должны проверить свой номер по 12 значениям.

Для этого вам не нужна функция факториала, вы можете строить эти значения по ходу дела, потому что n! = (n - 1)! · П. (Вы можете использовать функцию факториала, но будете делать одни и те же вычисления снова и снова, что расточительно. Это не имеет значения для этой проблемы с игрушкой, но стоит иметь в виду такие вещи.)

Итак, вот ваша функция, полностью переписанная:

int is_factorial(int n)
{
    int fact = 1;
    int k = 1;

    while (k < 13 && fact <= n) {
        fact *= k;
        if (n == fact) return k;
        k++;
    }    

    return 0;
}

Возвращает 0, когда n не факториал, в противном случае он возвращает число, которое n является факториалом. (Эта информация используется в любом случае, так почему бы не предоставить ее? Вызывающий может выбрать, использовать ли эту информацию или просто использовать ее в качестве значения истинности.)

Пока мы на этом, давайте настроим main Функция так, чтобы программа проверяла неправильный ввод и выводила дополнительную информацию, которую мы возвращаем:

int main(void)
{
    int n;

    printf("Enter a number: ");

    if (scanf("%d", &n) < 1) {
        printf("Illegal input!\n");
    } else {
        int m = is_factorial(n);

        if (m) {
            printf("%d is the factorial of %d!\n", n, m);
        } else {
            printf("%d is not a factorial!\n", n);
        }
    }

    return 0;
}

Здесь нужно уловить то, что вы должны использовать предупреждение компилятора, чтобы сообщить вам о простых ошибках, что вам следует избегать глобальных и статических переменных для закрытых проблем, подобных этим, и что циклы часто проще, чем рекурсия.

Другие вопросы по тегам