How would you write a non-recursive algorithm to compute n!
?
In the interests of science I ran some profiling on various implementations of algorithms to compute factorials. I created iterative, look up table, and recursive implementations of each in C# and C++. I limited the maximum input value to 12 or less, since 13! is greater than 2^32 (the maximum value capable of being held in a 32-bit int). Then, I ran each function 10 million times, cycling through the possible input values (i.e. incrementing i from 0 to 10 million, using i modulo 13 as the input parameter).
Here are the relative run-times for different implementations normalized to the iterative C++ figures:
C++ C#
---------------------
Iterative 1.0 1.6
Lookup .28 1.1
Recursive 2.4 2.6
And, for completeness, here are the relative run-times for implementations using 64-bit integers and allowing input values up to 20:
C++ C#
---------------------
Iterative 1.0 2.9
Lookup .16 .53
Recursive 1.9 3.9
int total = 1
loop while n > 1
total = total * n
n--
end while
public int factorialNonRecurse(int n) {
int product = 1;
for (int i = 2; i <= n; i++) {
product *= i;
}
return product;
}
long fact(int n)
{
long fact=1;
while(n>1)
fact*=n--;
return fact;
}
long fact(int n)
{
for(long fact=1;n>1;n--)
fact*=n;
return fact;
}
Non recursive factorial in Java. This solution is with custom iterator (to demonstrate iterator use :) ).
/**
* Non recursive factorial. Iterator version,
*/
package factiterator;
import java.math.BigInteger;
import java.util.Iterator;
public class FactIterator
{
public static void main(String[] args)
{
Iterable<BigInteger> fact = new Iterable<BigInteger>()
{
@Override
public Iterator<BigInteger> iterator()
{
return new Iterator<BigInteger>()
{
BigInteger i = BigInteger.ONE;
BigInteger total = BigInteger.ONE;
@Override
public boolean hasNext()
{
return true;
}
@Override
public BigInteger next()
{
total = total.multiply(i);
i = i.add(BigInteger.ONE);
return total;
}
@Override
public void remove()
{
throw new UnsupportedOperationException();
}
};
}
};
int i = 1;
for (BigInteger f : fact)
{
System.out.format("%d! is %s%n", i++, f);
}
}
}
For a non-recursive approach, it can't get simpler than this
int fac(int num) {
int f = 1;
for (int i = num; i > 0; i--)
f *= i;
return f;
}