如何检查否是否为阶乘?

时间:2014-01-18 04:48:31

标签: c performance algorithm factorial

我有一个问题,然后给出一些输入数n,我们必须检查no是否是其他一些no的因子。

INPUT 24,OUTPUT true
INPUT 25,OUTPUT false
我为它编写了以下程序: -

    int factorial(int num1) 
    {
        if(num1 > 1)
        {
           return num1* factorial(num1-1) ; 
        }
        else
        {
          return 1 ; 
        }
    }

    int is_factorial(int num2) 
    {
        int fact = 0  ; 
        int i = 0  ;
        while(fact < num2)
        {
             fact = factorial(i) ; 
             i++ ;
        }
        if(fact == num2)
        {
             return 0  ;
        }
        else
        {
             return -1;
        }
    }

这两个功能似乎都能正常工作 当我们反复为他们提供大量输入时,is_factorial将重复调用factorial,这实际上是浪费时间。
我还尝试维护一个用于阶乘的表

所以,我的问题是,是否有更有效的方法来检查数字是否是阶乘的?

6 个答案:

答案 0 :(得分:9)


一种方法是维护给定范围内的阶乘列表(例如所有64位无符号阶乘),并将其与之进行比较。考虑到阶乘的增加速度,该列表不会很大。事实上,这是一个实际为你生成函数的C元程序:

x!

运行时,您将获得以下功能:

(x+1)!

即使对于64位阶乘也非常简短有效。


如果您使用的是纯编程方法(没有查找表),则可以使用因子数为的属性:

(x+2)!

表示#include <stdio.h> int main (void) { unsigned long long last = 1ULL, current = 2ULL, mult = 2ULL; size_t szOut; puts ("int isFactorial (unsigned long long num) {"); puts (" static const unsigned long long arr[] = {"); szOut = printf (" %lluULL,", last); while (current / mult == last) { if (szOut > 50) szOut = printf ("\n ") - 1; szOut += printf (" %lluULL,", current); last = current; current *= ++mult; } puts ("\n };"); puts (" static const size_t len = sizeof (arr) / sizeof (*arr);"); puts (" for (size_t idx = 0; idx < len; idx++)"); puts (" if (arr[idx] == num)"); puts (" return 1;"); puts (" return 0;"); puts ("}"); return 0; } 的某些值。

因此,您可以简单地将测试编号除以int isFactorial (unsigned long long num) { static const unsigned long long arr[] = { 1ULL, 2ULL, 6ULL, 24ULL, 120ULL, 720ULL, 5040ULL, 40320ULL, 362880ULL, 3628800ULL, 39916800ULL, 479001600ULL, 6227020800ULL, 87178291200ULL, 1307674368000ULL, 20922789888000ULL, 355687428096000ULL, 6402373705728000ULL, 121645100408832000ULL, 2432902008176640000ULL, }; static const size_t len = sizeof (arr) / sizeof (*arr); for (size_t idx = 0; idx < len; idx++) if (arr[idx] == num) return 1; return 0; } ,然后1 x 2 x 3 x 4 x ... x (n-1) x n 然后n,依此类推。将发生以下两件事之一。

首先,你可能得到一个非整数结果,在这种情况下不是一个阶乘。

其次,您可能会从该部门获得2,在这种情况下, 是一个阶乘。

假设您的分歧是不可或缺的,以下代码将是一个很好的起点:

3

但是,对于效率,最好的选择可能是第一个。将计算成本移至构建阶段而不是运行时。与表查找相比,计算成本显着的情况下,这是一个标准技巧。

甚至可以使用查找表的二进制搜索使其效率更高,但这可能不是必需的,因为其中只有20个元素。

答案 1 :(得分:4)

如果数字是阶乘,那么对于某些n,其因子为1..n。

假设n是整数变量,我们可以执行以下操作:

int findFactNum(int test){
  for(int i=1, int sum=1; sum <= test; i++){
    sum *= i; //Increment factorial number
    if(sum == test)
        return i; //Factorial of i

   }
return 0; // factorial not found
}

现在将数字24传递给此功能块,它应该可以工作。此函数返回刚刚传递的阶乘的数字。

答案 2 :(得分:2)

通过简单检查数字是奇数还是偶数(使用%2),您可以加速至少一半的情况。没有奇数(禁止1)可以是任何其他数字的阶乘

答案 3 :(得分:0)

#include<stdio.h>
main()
{
      float i,a;
      scanf("%f",&a);
      for(i=2;a>1;i++)
      a/=i;
      if(a==1)
      printf("it is a factorial");
      else
      printf("not a factorial");
}

答案 4 :(得分:0)

您可以创建一个包含阶乘列表的数组:
就像在下面的代码中我创建了一个包含最多20个阶乘的数组。 现在你只需输入数字并检查它是否在阵列中..

#include <stdio.h>
int main()
{
    int b[19];
    int i, j = 0;
    int k, l;

    /*writing factorials*/
    for (i = 0; i <= 19; i++) {
        k = i + 1;
        b[i] = factorial(k);
    }
    printf("enter a number\n");
    scanf("%d", &l);
    for (j = 0; j <= 19; j++) {
        if (l == b[j]) {
            printf("given number is a factorial of %d\n", j + 1);
        }
        if (j == 19 && l != b[j]) {
            printf("given number is not a factorial number\n");
        }
    }
}
int factorial(int a)
{
    int i;
    int facto = 1;
    for (i = 1; i <= a; i++) {
        facto = facto * i;
    }
    return facto;
}

答案 5 :(得分:-1)

from flask import request

from my_app.api.v1.views import index as v1_index
from my_app.api.v2.views import index as v2_index

.... other code ...


@app.route('/api')
def index():
    api_version = request.args.get('v', '1.0')
    if api_version == '1.0':
        return v1_index()
    elif api_version == '2.0':
        return v2_index()
    else:
        return 'Unsupported API version.'