求解幂次式P^N,这里介绍三种方法(或者可以说两种)
一、朴素循环法(效率低)O(N)
int Get_mi(int p,int n){
int temp=p;
for(int i=1;i<n;i++)
p*=temp;
return p;
}
二、二进制法递归求解(递归次数为O(len),len为n的二进制长度。理论上时间复杂度要大于O(len),由于要使用系统栈)
给出下面一个例子。
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为奇数);
那么就可以据此编写递归函数了。
int Get_mi(int p,int n){
if(n==1) return p;
if(n==0) return 1;
if(n&1) return Get_mi(p,n>>1)*Get_mi(p,n>>1)*p;
else return Get_mi(p,n>>1)*Get_mi(p,n>>1);
}
int Get_mi(int p,int n){
if(n==1) return p;
if(n==0) return 1;
if(n&1) return Get_mi(p*p,n>>1)*p;
else return Get_mi(p*p,n>>1);
}
三、最高效的算法。将上述递归算法改为非递归形式即可。利用了二进制思想:例如
2^3,3二进制为011,末尾位1,则乘以2,前一位为1,则乘以2*2,第一位为0,则不乘。算法结束。真正实现了时间复杂度为O(len),len为p二进制位数
下面是代码:
int Get_mi(int p,int n){
int sq=1;
while(n>0){
if(n&1) sq*=p;
p*=p;
n>>=1;
}
return sq;
}