How would you write a non-recursive algorithm to calculate factorials?

后端 未结 22 886
不思量自难忘°
不思量自难忘° 2020-12-10 11:39

How would you write a non-recursive algorithm to compute n!?

相关标签:
22条回答
  • 2020-12-10 12:08

    Unless you have arbitrary-length integers like in Python, I would store the precomputed values of factorial() in an array of about 20 longs, and use the argument n as the index. The rate of growth of n! is rather high, and computing 20! or 21! you'll get an overflow anyway, even on 64-bit machines.

    0 讨论(0)
  • 2020-12-10 12:08

    Pseudo code

    total = 1
    For i = 1 To n
        total *= i
    Next
    
    0 讨论(0)
  • 2020-12-10 12:09

    Here's the precomputed function, except actually correct. As been said, 13! overflows, so there is no point in calculating such a small range of values. 64 bit is larger, but I would expect the range to still be rather reasonable.

    int factorial(int i) {
        static int factorials[] = {1, 1, 2, 6, 24, 120, 720, 
                5040, 40320, 362880, 3628800, 39916800, 479001600};
        if (i<0 || i>12) {
            fprintf(stderr, "Factorial input out of range\n");
            exit(EXIT_FAILURE); // You could also return an error code here
        }
        return factorials[i];
    } 
    

    Source: http://ctips.pbwiki.com/Factorial

    0 讨论(0)
  • 2020-12-10 12:09

    At run time this is non-recursive. At compile time it is recursive. Run-time performance should be O(1).

    //Note: many compilers have an upper limit on the number of recursive templates allowed.
    
    template <int N>
    struct Factorial 
    {
        enum { value = N * Factorial<N - 1>::value };
    };
    
    template <>
    struct Factorial<0> 
    {
        enum { value = 1 };
    };
    
    // Factorial<4>::value == 24
    // Factorial<0>::value == 1
    void foo()
    {
        int x = Factorial<4>::value; // == 24
        int y = Factorial<0>::value; // == 1
    }
    
    0 讨论(0)
  • 2020-12-10 12:10

    assuming you wanted to be able to deal with some really huge numbers, I would code it as follows. This implementation would be for if you wanted a decent amount of speed for common cases (low numbers), but wanted to be able to handle some super hefty calculations. I would consider this the most complete answer in theory. In practice I doubt you would need to compute such large factorials for anything other than a homework problem

    #define int MAX_PRECALCFACTORIAL = 13;
    
    public double factorial(int n) {
      ASSERT(n>0);
      int[MAX_PRECALCFACTORIAL] fact = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 
                    362880, 3628800, 39916800, 479001600};
      if(n < MAX_PRECALCFACTORIAL)
        return (double)fact[n];
    
      //else we are at least n big
      double total = (float)fact[MAX_PRECALCFACTORIAL-1]
      for(int i = MAX_PRECALCFACTORIAL; i <= n; i++)
      {
        total *= (double)i;  //cost of incrimenting a double often equal or more than casting
      }
      return total;
    
    }
    
    0 讨论(0)
  • 2020-12-10 12:11

    Since an Int32 is going to overflow on anything bigger than 12! anyway, just do:

    public int factorial(int n) {
      int[] fact = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 
                    362880, 3628800, 39916800, 479001600};
      return fact[n];
    }
    
    0 讨论(0)
提交回复
热议问题