一、为何有快速幂?
我们正常在求解关于a的b次幂的问题时,都是一个一个循环去乘:
#include <iostream>
using namespace std;
int a,b; //求a的b次幂
int main()
{
cin >> a >> b;
int ans = 1; //用来保存答案
for(int i = 0; i < b; i++) //循环乘b次
{
ans *= a;
}
cout << ans;
return 0;
}
代码很简单,但是有个致命的缺点:速度太慢了。当b的值靠近2的30次幂时,循环次数也来到了十亿次左右,这是显然不能接受的。
于是就有了这样一种可以快速算a的b次幂的方法:快速幂。
二、快速幂
快速幂,顾名思义,快速计算幂的方式,那么如何能够做到快速呢?我们知道,如果要求,就只需要
。也就是公式:
,这个一会儿会用。
按照这种想法,先来看个数字小一点的,比如。这里的8、2、1是随便选的数字吗?对于学习计算机的我们来说,肯定很熟悉,因为这几个数字与二进制有着密切的关系。
那么到底是什么关系呢?仔细观察不难发现:11的二进制为1011,这里面的每个1就代表着十进制的8、2、1。那就恍然大悟了,这样求11次幂,我只需要乘这样的三个数字就行了,再结合刚才说的,我们发现每个因子都是2的整数次幂也就是这种形式。再去观察11的二进制1011,从最后一位开始,把a翻倍,如果是1,就乘进来,如果是0就不管。
这样整体思路就清晰了。下面就是处理这个1011,如何来转化我们需要的信息,毕竟输入的是11,你大可以自己写个算法把11转化为二进制数,但是我是肯定不会这样做的啦,其实计算机语言大多支持一种特殊的运算--位运算。我们用位运算就可以直接进行二进制的算数了,如果对位运算不了解,可以找我的另一篇一分钟算法系列中关于位运算的文章。
三、代码
#include <iostream>
using namespace std;
int a, b;
int quickpower(int a, int b) // 快速幂求a的b次幂
{
int ans = 1; //用来保存结果
int base = a; //用来实现a的平方以及a平方的平方……
while (b != 0) //b的二进制还有位
{
if (b & 1) //与运算,只有b的二进制形式末尾是1,结果才是1
{
ans *= base; //结果的累积
}
base *= base; a平方以及a平方的平方……
b >>= 1; //右移运算符,把b的二进制数各个位置向右移动一位,例如1011右移一位变为101
}
return ans; //结果返回
}
int main()
{
cin >> a >> b;
int m = quickpower(a, b);
cout << m;
return 0;
}
四、结束
本文实现了快速幂的计算方法,当然对于快速幂的理解不止这一种,可以在网上找到很多的资料进行参考学习。
同时,题目一般都会结合高精度,如果你还不知道高精度是什么,可以找我关于高精度的文章介绍,或者网上优秀博主的讲解。
声明:本文为学习时的记录,如有错误,请及时私信。