给定非常大的数字N ,任务是使用Log查找数字的阶乘。
Factorial of a non-negative integer is the multiplication of all integers smaller than or equal to N.
前面我们已经讨论了一个简单的程序来查找本文中的阶乘。在这里,我们将讨论找到大数阶乘的有效方法。
例子:
Input: N = 100
Output: 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Input: N = 50
Output: 30414093201713378043612608166064768844377641568960512000000000000
方法:最常见的迭代版本在预期的O(N)时间中运行。但是随着数字变大,假设乘法需要固定的时间将是错误的。天真的方法需要O(K * M)的时间进行乘法运算,其中K是乘数的长度,M是被乘数的长度。因此,该想法是使用对数属性:
我们知道和
所以:
另一个属性是
用ln(N!)的值代替。
下面是上述方法的实现:
C++
// C++ program to compute the
// factorial of big numbers
#include
using namespace std;
// Maximum number of digits
// in output
#define MAX 1000
// Function to find the factorial
// of large number and return
// them in string format
string factorial(long long n)
{
if (n > MAX) {
cout << " Integer Overflow"
<< endl;
return "";
}
long long counter;
long double sum = 0;
// Base case
if (n == 0)
return "1";
// Calculate the sum of
// logarithmic values
for (counter = 1; counter <= n;
counter++) {
sum = sum + log(counter);
}
// Number becomes too big to hold in
// unsigned long integers.
// Hence converted to string
// Answer is sometimes under
// estimated due to floating point
// operations so round() is used
string result
= to_string(round(exp(sum)));
return result;
}
// Driver code
int main()
{
clock_t tStart = clock();
string str;
str = factorial(100);
cout << "The factorial is: "
<< str << endl;
// Calculates the time taken
// by the algorithm to execute
cout << "Time taken: " << setprecision(10)
<< ((double)(clock() - tStart)
/ CLOCKS_PER_SEC)
<< " s" << endl;
}
The factorial is: 93326215443944231979346762015249956831505959550546075483971433508015162170687116519232751238036777284091181469944786448222582618323317549251483571058789842944.000000
Time taken: 0.000114 s
时间复杂度: O(N) ,其中N是给定的数字。