📜  使用对数恒等式的大数阶乘

📅  最后修改于: 2021-04-29 07:13:11             🧑  作者: Mango

给定非常大的数字N ,任务是使用Log查找数字的阶乘。

前面我们已经讨论了一个简单的程序来查找本文中的阶乘。在这里,我们将讨论找到大数阶乘的有效方法。

例子:

方法:最常见的迭代版本在预期的O(N)时间中运行。但是随着数字变大,假设乘法需要固定的时间将是错误的。天真的方法需要O(K * M)的时间进行乘法运算,其中K是乘数的长度,M是被乘数的长度。因此,该想法是使用对数属性:

我们知道N! = \prod_{i=1}^{N} i ln (ab) = ln(a) + ln(b)

所以:
ln (N!) = ln(}\prod_{i=1}^{N} i) = \sum_{i=1}^{N} ln(i)

另一个属性是
e^{ln(N!)} = N!
用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;
}


输出:

时间复杂度: O(N) ,其中N是给定的数字。