本文已参与「新人创作礼」活动,一起开启掘金创作之路
昨天刚刚学了快速幂运算来加快幂运算,即a^x^,来总结一下 我们最常用的幂运算是,使用一个循环语句来控制循环乘或者直接使用库函数pow(int a,int n)来实现幂运算。
使用循环语句来进行幂运算,时间复杂度是O(n) 再进行网上查询了解到pow库函数的时间复杂度会比O(n)还大 了解链接为www.cnblogs.com/zhanghuaye/… 所以我们使用一种新的算法来解决超时问题
快速幂运算 快速幂运算实际上是用了二分的思想,不过二分法还没自学到那,就直接和你们说原理了 比如a^56^ ,我们如果不一个一个a相乘的话,怎么解决算才会减少时间呢,在我们实际运算一个幂运算的时候,给你一个2^8^,你是不是会进行2^4^ *2^4^来算2的8次方
不会吧不会吧真的还有人一个一个乘来算出2的8次方叭!
重新回到正题,a^56^ = (a^28^)^2^ = ((a^14^)^2^)^2^= ((a^7^)^2^)^2^)^2^ ,到奇数的时候怎么办? a^7^ = a^(3+3+1)^=(a^3^)^2^ * a,直到化到a,这样算下来时间复杂度就是O(logn),明显大大缩短了时间。
接下来敲一下代码 quick pow简称qp
int qp(int a,int n){
int ans =1;
while(n){
if(n&1) ans *=a;
a*=a;
n>>=1;
return ans;
}
这就是快速幂的代码,就这么短就缩短了大部分时间 接下来说一下代码细节 这里是运用了二进制转换来达到代码简便。
比如10的二进制为1010,计算2^10^的时候可以如下计算
我们知道2^10^ =2 (2^0^*0+2^1^*1+2^2^*0+2^3^*1)
所以计算a^n^的时候也一样
化为二进制的好处在于
可让a=a * a一直执行,当取到n的二进制不为0的时候就进行乘进去。
n&1的意思是 n的二进制和1进行 位与预算 插入一个位与预算的知识,比如10和1位与运算,10的二进制为1010,1的二进制就是1,位与运算的规则是,每个位置上一一对应,若同为1,则为1,如以下: 1010 0001 —— 0000 一个整数和1进行位与运算,即是取这个整数二进制的最后一位数,再配合右移运算符>>便可取完整个整数的二进制每个位数。
最后当n>>1 =0的时候结束循环,即可求得a^n^.