快速阶乘运算

在前一篇blog中提到了logn复杂度求出C(n,r),利用此结果在(logn)^2复杂度下计算n!

oh, fuck!!! 校园招聘微软的三面面试官出了这道bug题。。。

分析:利用下面的公式可以降低复杂度

由于C(n, n/2)需要logn复杂度计算出来,加上n!所需的logn,所以总体复杂度为(logn)^2,代码如下:

#include <iostream>
#include <iterator>
#include <algorithm>

using namespace std;

#define MAXSIZE 100
unsigned long answer[MAXSIZE];

unsigned long long int power(unsigned long base, unsigned long exp)
{
	unsigned long long int result = 1;
	while (exp)
	{
		if (exp & 0x01)
			result *= base;
		base *= base;
		exp >>= 1;
	}

	return result;
}

unsigned long cn2(unsigned long n)
{
	unsigned long x = (1 << n) + 1;
	unsigned long mask = (1 << n) - 1;

	return (power(x, n) >> ((n >> 1) * n)) & mask;
}

unsigned long factorial(unsigned long n)
{
	unsigned long temp;

	if (n == 1)
		return 1;
	else if (n & 0x01 == 1)
		return n * factorial(n - 1);
	else
	{
		temp = factorial(n >> 1);
		return cn2(n) * temp * temp;
	}
}

void main()
{
	int number = 4;
	unsigned long result = factorial(number);
	cout << "result = " << result << endl;
}

更快速的阶乘运算,只需要log(n)复杂度

我们可以看到cn2(n)需要logn的复杂度计算出来,可以提前计算出来存放在数组中,由于每次计算C(n,n/2), C(n/2, n/4), ... 这样在求解power的过程中,就可以计算出来~

#include <iostream>
#include <iterator>
#include <algorithm>

using namespace std;

#define MAXSIZE 100
unsigned long mask;
unsigned cnrs[MAXSIZE];
int number;
int p_size;

unsigned long power(unsigned long n, unsigned long m)
{
	unsigned long temp;

	if (m == 1)
		temp = n;
	else if (m & 0x01 != 0)
		temp = n * power(n, m - 1);
	else
	{
		temp = power(n, m >> 1);
		temp *= temp;
		cnrs[number++] = (temp >> ((m >> 1) * p_size)) & mask;
	}

	return temp;
}

unsigned factor(unsigned long n)
{
	unsigned long temp;

	if (n == 1)
		return 1;
	else if (n & 0x01 == 1)
		return n * factor(n - 1);
	else
	{
		temp = factor(n >> 1);
		return cnrs[number++] * temp * temp;
	}
}

unsigned long factorial(unsigned long n)
{
	unsigned long x = (1 << n) + 1;

	number = 0;
	mask = (1 << n) - 1;
	p_size = n;
	power(x, n);
	number = 0;

	return factor(n); 
}

void main()
{
	int number = 6;
	unsigned long result = factorial(number);
	cout << "result = " << result << endl;
	copy(cnrs, cnrs + 10, ostream_iterator<int>(cout, " "));
}




### 回答1: 下面是快速幂计算阶乘的代码: ``` def fast_factorial(n): if n == 0: return 1 elif n == 1: return 1 elif n % 2 == 0: return fast_factorial(n // 2) ** 2 else: return n * fast_factorial(n - 1) ``` 使用方法:调用 `fast_factorial(n)` 即可得到 `n!` 的值。 注意:由于快速幂算法的时间复杂度为 O(log n),所以计算阶乘的速度要比传统算法快得多。但是,由于算法的复杂度取决于对数的底数,所以在实际应用中,这种优化可能并不明显。 ### 回答2: 下面是一个使用快速幂计算阶乘的代码示例。 ```python def factorial(n): if n < 0: return None if n == 0 or n == 1: return 1 result = 1 base = 2 while n > 1: if n % 2 == 1: result *= base base = base * base n = n // 2 return result * base ``` 在这个代码中,我们使用了快速幂的思想来计算阶乘。首先,我们设置一个变量result来保存最终的计算结果,初始值为1。我们还设置一个变量base来保存base ^ n,初始值为2,n为要计算阶乘的数。然后,我们进入一个while循环,当n大于1时,进行循环计算。 在循环中,我们首先判断n是否为奇数,如果是奇数,我们就将result乘以base。然后,我们将base乘以base,相当于将base的指数加倍。接着,我们将n除以2,相当于将指数减半。 循环结束后,我们最终的计算结果为result * base,即阶乘的值。 需要注意的是,这个代码对输入的n做了一些条件判断。当n小于0时,返回None,表示输入无效。当n等于0或者1时,直接返回1,因为0的阶乘和1的阶乘都等于1。 希望这个代码能帮助到你,如果有任何问题,请随时提问。 ### 回答3: 快速幂算法是一种用于快速计算幂的方法。在计算阶乘时,可以利用快速幂算法来减少计算次数。 以下是快速幂计算阶乘的代码: ``` def fast_power(base, exponent, mod): result = 1 while exponent > 0: if exponent % 2 == 1: result = (result * base) % mod base = (base * base) % mod exponent = exponent // 2 return result def factorial(n, mod): result = 1 for i in range(1, n+1): result = (result * fast_power(i, n, mod)) % mod return result # 例子:计算10的阶乘模1000000007 mod = 1000000007 n = 10 result = factorial(n, mod) print(result) ``` 在这个代码中,`fast_power`函数使用快速幂算法来计算幂的结果。`factorial`函数则通过循环调用`fast_power`来计算阶乘的结果,并且使用取模运算来防止数值溢出。最后,可以根据需要设定模数`mod`和阶乘的数值`n`来得到结果。 以上就是快速幂计算阶乘的代码。希望对您有帮助!
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值