昨天看到学校某群里的18级小学弟提到快速幂这个东西,心头一颤,毕竟自己未曾听过,于是乎抽出时间了解了一下,顺便发一贴来谈谈自己的思路。
常规幂运算的基本写法
#define ans=1
for(int i=1;i<=b;i++)
{
ans*=a;
}
不难发现,当数值b,即次方,足够大的时候,运行所花费的时间也会变得非常的大
而当数值a,即基数,也足够大的时候,运行所需花费的空间也是十分可怕的
因此,快速幂应运而生。相比于常规幂运算,快速幂在时间和空间上的消耗会少很多。而且写法也不难理解。
快速幂运算
话不多说,先贴代码
private static int ksm(int a, int b) {
int s = 1;
while (b > 0) {
if (b % 2 == 1) { //判断二进制表示下的b的最后一位是否为1
s = s * a;
}
a = a * a;
b = b >> 1; //用位运算代替除2操作
}
return s;
}
幂运算的理解最主要的还是要看懂有关指数的那部分,下面我们以2^7为例进行讲解。
7的二进制可表示为0000 0111,而代码中的if语句判断的就是指数的二进制表示法中的最后一位是否为1。当然,无论指数的最后一位是否为1,我们都需要将所需判断的二进制表示出来的指数的位数一步步往前移,然后再判断指数的所有的有效位数是否全部处理了,这里,我采用位运算进行相应功能的实现。
改进
在写完这篇个人理解之前,我还浏览了一些相关内容的blog,其中采用‘&’来判断最后一位是否为1 的写法还不错,但是需要理清返回值是什么。除此之外,还有些有关快速幂取模的算法,私以为,还需搞懂快速幂的写法才能更好的加以理解。
附:文中不合理之处还望看见的各位同仁加以之处,免得误人子弟,跪谢