【问题标题】:Why is my CheckFactorial script not working? [closed]为什么我的 CheckFactorial 脚本不起作用? [关闭]
【发布时间】:2018-10-28 00:32:25
【问题描述】:
#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,它应该是 Yes,因为 3! = 6 但如果输入 8 则不起作用。

我不认为这是重复的,因为我做的方法不同。

请注意,我不太擅长 C,所以如果有任何额外的提示,我们将不胜感激。

【问题讨论】:

标签: c math factorial


【解决方案1】:

您需要纠正 3 个错误才能使该程序正常运行。

  1. 您将factorialwhichnumberfactorialnumber 进行比较,这是错误的。
  currnumber = factorial(whichnumber);
            if (currnumber == factorial(number)) //<----never be true
            {
                return 1;
            }

您应该将factorialwhichnumbernumber 进行比较

 currnumber = factorial(whichnumber);

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

2 。您应该在factorial 函数中初始化fac 变量,否则它会占用一些垃圾值。

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

3。在计算factorial 之后,您应该返回fact 的值。

  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
}

【讨论】:

    【解决方案2】:

    有人向您指出,您不会从函数中返回值,而是使用未初始化的值。这些错误很容易产生,但也很容易捕获:为编译器启用警告,它们会告诉你这些事情。

    Suvojit 的回答告诉您阶乘函数出了什么问题。不幸的是,您的阶乘检查有更多问题:

    • 您将检查的数字设为全局变量。这应该是函数的一个参数,这样您就可以像应该的那样调用它:is_factorial(n)
    • 您将计数器设为static 变量。这就像一个全局变量,但有一个限制,它只能在这个函数中知道,这意味着你不能从外部更改它。如果您的程序要检查多个数字,则第二次调用会从您之前中断的地方开始,这会导致错误的结果。
    • 当然,这是您在实现中想要的,因为您使用递归算法。在这种情况下,这不是一个好的选择。使用循环。
    • 您的条件何时停止迭代(或何时中断循环)检查该数字与您对其进行阶乘的数字。您应该针对阶乘本身进行测试。

    请注意,典型的int 有 32 位,可以表示最大为 2³¹ 的正值。 13阶乘!已经超过了这个限制。因此,您必须对照 12 个值检查您的号码。

    您不需要阶乘函数,您可以随时构建这些值,因为n! = (n - 1)! · n。 (你可以使用阶乘函数,但会一遍又一遍地做同样的计算,这很浪费。这对这个玩具问题没关系,但值得记住这些事情。)

    这是你的函数,完全重写:

    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;
    }
    

    n 不是阶乘时返回0,否则返回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;
    }
    

    这里要注意的是,您应该使用编译器警告来告诉您简单的错误,对于此类封闭问题,您应该避免使用全局变量和静态变量,并且循环通常比递归更简单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 2014-03-21
      • 2012-10-07
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多