快速求幂算法
来源:互联网 发布:windows 7 mstsc 会话 编辑:程序博客网 时间:2024/04/25 14:57
我们知道在数学表达式中pow(x, n)表示求x^n的幂。一般情况下,如果我们要写一个程序的话,最简单的程序可能是这样的:
- int pow(int x, int n){
- int result = 1;
- while (n != 0){
- result = result *x;
- n = n -1;
- }
- return result;
- }
通过使用如上的程序,2^4 = 2 * 2 * 2 * 2,在程序中做了4-1=3次乘法,但是有没有更高效的算法来减少乘法的次数呢。
答案是肯定的。
我们知道
2^9 = 2^4 * 2^4 * 2
2^8 = 2^4 * 2^4
2^7 = 2^3 * 2^3 * 2
2^6 = 2^3 * 2^3
……
我们发现了什么?
x^n = x^(n/2) * x^(n/2) (n为偶数)
x^n = x^(n/2) * x^(n/2) * n (n为奇数);
这样的话我们就可以使用递归的方法将问题化为一半一半的解法。(divide and conquer)
程序如下:
- int pow2(int x, int n){
- if (n == 1) return x;
- if (n == 0) return 1;
- else if (n & 1)
- return pow2(x, n/2) * pow2(x, n/2) * x;
- else
- return pow2(x, n/2) * pow2(x, n/2);
- }
- int pow2(int x, int n){
- if (n == 1) return x;
- if (n == 0) return 1;
- else if (n & 1)
- return pow(x * x, n >>1)*x; //不同之处
- else
- return pow(x *x, n>>1); //不同之处
- }
其实,这两种写法是相同,君不见pow(x, n) * pow(x, n) = pow(x*x, n)
递归有很多好处,其中之一就是代码简洁,可读性强,但是也有不好的地方,如果n的位数足够大(假设整个结果不溢出的情况),那么其使用的栈可能会产生溢出的情况。
现在既然我们已经有了一个递归的方法,那么写一个非递归的方法就水到渠成了。我们要想想如何去写这个非递归的程序了。
例如2^9 = 2^(1001) 括号里面是二进制数制。在我们做2^9乘法的时候,我们是用这样的方法来乘的:2^9 = 2^8 * 2^1
也就是只有在二进制数位上为1时乘一个2^n,而在二进制数位上为0时,则不乘。那么我们的程序就有了:
- int pow3(int x, int n)
- {
- int result = 1;
- while (n > 0) {
- if (n & 1) // n & 1 等价于 (n % 2) == 1
- result *= x;
- x *= x;
- n >>= 1; // n >>= 1 等价于 n /= 2
- }
- return result;
- }
- 快速求幂算法
- 快速求幂算法
- 快速求幂算法
- 快速求幂算法
- 快速求幂算法
- 快速求幂算法
- 快速求幂算法
- 快速求幂算法
- 快速求幂算法
- 快速求幂算法
- 快速求幂算法
- 常用算法-快速求幂
- 【算法】矩阵快速求幂
- 快速求幂二分算法
- 算法 二分求幂(快速取幂)
- 非递归快速求幂算法
- 经典算法~~快速求幂的方法
- LeetCode Super Pow(快速求幂算法)
- 前端性能优化
- C++拷贝构造函数详解(转载---原作者写的很好,不过还是放在自己这里查阅起来方便。)
- 深入研究之回音抑制算法(echo canceller)
- 今天开始, 养成写博客的习惯
- 配置
- 快速求幂算法
- HDOJ2035(快速幂取模)
- CentOS安装时选择为简体中文,完成后设置支持英文或中文方法
- extjs和js定时器
- 四层和七层负载均衡的区别
- bash中的转义
- asp.net 工厂模式 各层 代码 用处
- Struts1学习笔记——动态LazyValidatorForm技术
- 无法启动此程序,因为计算机中丢失MSVCP100D.dll。尝试重新安装该程序以解决此问题。