看到一道很简单的求整数次幂的题目,但是看到讨论区有用快速幂做的,我居然不知道这是什么?于是学之,记之(其实这玩意在大一的计算机导论里面提到过)
什么是快速幂
快速幂是一种简化运算底数的n次幂的算法,理论上其时间复杂度为 O(log₂N), 而一般的朴素算法则需要O(N)的时间复杂度。简单来说快速幂其实就是抽取了指数中的2的n次幂,将其转换为时间复杂度为O(1)的二进制移位运算,所以相应地,时间复杂度降低为O(log₂N)。
具体思路
首先以
b
13
b^{13}
b13为例
可以把指数13用二进制表示,即为1101,将二进制数字1101直观地表现为十进制则是如下的等式:
13
=
1
∗
2
3
+
1
∗
2
2
+
0
∗
2
1
+
1
∗
2
0
13=1*2^3+1*2^2+0*2^1+1*2^0
13=1∗23+1∗22+0∗21+1∗20
这样一来,要求的结果可以如下算出:
b
13
=
b
2
3
∗
b
2
2
∗
b
2
0
b^{13}=b^{2^3}*b^{2^2}*b^{2^0}
b13=b23∗b22∗b20 或者
b
13
=
b
2
3
∗
b
2
2
∗
(
0
∗
b
2
1
)
∗
b
2
0
b^{13}=b^{2^3}*b^{2^2}*(0*b^{2^1})*b^{2^0}
b13=b23∗b22∗(0∗b21)∗b20(把0补上便于理解)
四个项对应1101
如果更加直观地展现为快速幂的思想,应该这样写(实际上就是换了个写法然后把顺序也调换了一下,看不懂的可以复习下高一数学):
b
1
∗
(
b
2
)
2
∗
(
(
b
2
)
2
)
2
b^1*{(b^2)}^2*{({(b^2)}^2)}^2
b1∗(b2)2∗((b2)2)2 或者
b
1
∗
(
0
∗
b
2
)
∗
(
b
2
)
2
∗
(
(
b
2
)
2
)
2
b^1*(0*b^2)*{(b^2)}^2*{({(b^2)}^2)}^2
b1∗(0∗b2)∗(b2)2∗((b2)2)2 (把0补上便于理解)
四个项1011(从右边读起,程序中每次循环了右移一位,并且读取末位)
这样一来,递归的模子就有了,代码也就不难写出来了,java代码:
public int testPosition(int base,int exponent) {
int result = 1=;
while (exponent!=0) {
if ((exponent & 1)!=0) {
result *= base;
}
base *= base;
exponent >>= 1;
}
return result;
}
写完,告辞!