我们在一般求幂的时候常用的方法很简单,求是挨个去求就是了
int pow(int x, int n){
int m=1;
while(n!=0){
m=m*x;
n=n-1;
}
return m;
}
但是这种方法实在是太慢了,例子
快速求正整数次幂,当然不能直接死乘。举个例子:
3 ^ 999 = 3 * 3 * 3 * … * 3
直接乘要做998次乘法。但事实上可以这样做,先求出2^k次幂:
3 ^ 2 = 3 * 3
3 ^ 4 = (3 ^ 2) * (3 ^ 2)
3 ^ 8 = (3 ^ 4) * (3 ^ 4)
3 ^ 16 = (3 ^ 8) * (3 ^ 8)
3 ^ 32 = (3 ^ 16) * (3 ^ 16)
3 ^ 64 = (3 ^ 32) * (3 ^ 32)
3 ^ 128 = (3 ^ 64) * (3 ^ 64)
3 ^ 256 = (3 ^ 128) * (3 ^ 128)
3 ^ 512 = (3 ^ 256) * (3 ^ 256)
相互结合
x^n = x^(n/2) * x^(n/2) (n为偶数)
x^n = x^(n/2) * x^(n/2) * n (n为奇数);
核心思想就是这样了。
用二进制与运算,和移位的思想就可以轻松搞定了
int pow2(int x, int n){
if (n == 1) return x;
if (n == 0) return 1;
else if (n & 1) //A:
return pow(x * x, n >>1)*x; //B
else
return pow(x *x, n>>1);
}
A:代表的是如果n%2==1的意思,也可以直接写成if(n%2==1)
B:n>>1 代表的向右移位一位的意思,举个例子,若是n==3,n>>1,则是1 ,若n==4,n>>1,则是2,因此我总结如果n>>X,
则那么n/(2的X次);
但是递归太慢了,这样不是最好的,所以还可以这样写嘛:
int pow(int x, int n)
{
int m = 1;
while (n > 0) {
if (n & 1) // n & 1 等价于 (n % 2) == 1
m *= x;
x *= x;
n >>= 1; // n >>= 1 等价于 n /= 2
}
return m;
}