快速阶乘算法
从网上引用,和上一篇出自同一博客。
借用上一篇的理论,可以在log2n内计算阶乘。
原理:如上图。
代码:
1 #include <iostream> 2 #include <iterator> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define MAXSIZE 100 8 unsigned long answer[MAXSIZE]; 9 10 unsigned long long int power(unsigned long base, unsigned long exp) 11 { 12 unsigned long long int result = 1; 13 while (exp) 14 { 15 if (exp & 0x01) 16 result *= base; 17 base *= base; 18 exp >>= 1; 19 } 20 21 return result; 22 } 23 24 unsigned long cn2(unsigned long n) 25 { 26 unsigned long x = (1 << n) + 1; 27 unsigned long mask = (1 << n) - 1; 28 29 return (power(x, n) >> ((n >> 1) * n)) & mask; 30 } 31 32 unsigned long factorial(unsigned long n) 33 { 34 unsigned long temp; 35 36 if (n == 1) 37 return 1; 38 else if (n & 0x01 == 1) 39 return n * factorial(n - 1); 40 else 41 { 42 temp = factorial(n >> 1); 43 return cn2(n) * temp * temp; 44 } 45 } 46 47 void main() 48 { 49 int number = 4; 50 unsigned long result = factorial(number); 51 cout << "result = " << result << endl; 52 }
还可以logn内完成,但需要把C(N,N/2),C(N/2,N/4),C(N/4,N/8).....打出来。
1 #include <iostream> 2 #include <iterator> 3 #include <algorithm> 4 5 using namespace std; 6 7 #define MAXSIZE 100 8 unsigned long mask; 9 unsigned cnrs[MAXSIZE]; 10 int number; 11 int p_size; 12 13 unsigned long power(unsigned long n, unsigned long m) 14 { 15 unsigned long temp; 16 17 if (m == 1) 18 temp = n; 19 else if (m & 0x01 != 0) 20 temp = n * power(n, m - 1); 21 else 22 { 23 temp = power(n, m >> 1); 24 temp *= temp; 25 cnrs[number++] = (temp >> ((m >> 1) * p_size)) & mask; 26 } 27 28 return temp; 29 } 30 31 unsigned factor(unsigned long n) 32 { 33 unsigned long temp; 34 35 if (n == 1) 36 return 1; 37 else if (n & 0x01 == 1) 38 return n * factor(n - 1); 39 else 40 { 41 temp = factor(n >> 1); 42 return cnrs[number++] * temp * temp; 43 } 44 } 45 46 unsigned long factorial(unsigned long n) 47 { 48 unsigned long x = (1 << n) + 1; 49 50 number = 0; 51 mask = (1 << n) - 1; 52 p_size = n; 53 power(x, n); 54 number = 0; 55 56 return factor(n); 57 } 58 59 void main() 60 { 61 int number = 6; 62 unsigned long result = factorial(number); 63 cout << "result = " << result << endl; 64 copy(cnrs, cnrs + 10, ostream_iterator<int>(cout, " ")); 65 }