快速幂

前言

  在写这篇博客之前,我浏览了很多介绍快速幂的博客,希望从中借鉴其精华,来弥补我可能有的考虑不足之处。
  我发现很多的大神在描述快速幂的原理实现时都利用了二进制权值 (不知道各位小可爱对这个词儿熟悉不)。二进制权值对我来说是个新词,虽然我去了解它的时候发现它并不难理解,但我还是决定用更接地气的方法,来解释快速幂的原理及实现。

实现代码

先不说其他的,直接怼代码

int kmi(int a,int n)   //a为底数,n为指数
{
    int ans=1;      //用于存储的结果
    while(n>0)
    {
        if(n&1)     //指数为奇数时
           ans*=a;
        a=a*a;  
        n>>=1;      //指数右移
    }
    return ans;
}

代码中用到了位运算中的与操作运算符&和二进制运算符>>。如果你对这两个或其他的运算符不甚了解,那就点这里。接地气的方法在下面哦

算法原理

下面通过分别展现普通求幂和快速求幂的运算过程,让你直观的看到快速幂是怎么更“快”的。

以求2^11为例

  • 普通算法:
    211 = 2 * 210 = 4 * 29 … = 256 * 23 = 512 * 22 = 1024 * 21 = 2048。需要计算10次

  • 快速算法:
    211 = 2 * 45 = 8 * 162 = 8 * 2561 = 2048。只需要计算3次!!!

通过上面的例子我们可以发现,普通的算法每运算一次,底数不变,指数比原来少一。所以当求an时,就需要计算n次,故其时间复杂度为O(n)。而快速幂算法每运算一次,底数变为原来的平方,指数变为原来的二分之一(快画重点!)所以只需要计算log2n次(当指数为1时),就可以计算出an的结果。姑其时间复杂度为O(long2n)。
总结一下:简单来说,快速幂是通过对指数的压缩来减少运算的次数的。

算法实现

总的来说,我们可以把算法的过程分为两步

  1. 判断指数的奇偶性,如果为奇数,就让ans=ans*度数。其中ans是用来存储结果的变量。
  2. 让底数变为原来的平方,即a=a*a;让指数变为原来的二分之一,即n>>1;

注意:的是循环结束的条件为n<=0,事实上当n==1时就计算出结果了,但由于位移操作放在循环尾部,所以1变成了0

有人说我写代码时不想搞&、>>这些花里胡哨的咋弄

这简单

int kmi(int a,int n)
{
    int ans=1;
    while(n>0)
    {
        if(n%2!=0)   //只要能判断奇偶性,用什么方法无所谓,不过n&1要比这种效率高一点
          ans*=a;
        a=a*a;
        n/=2;       
    }
    return ans;
}

这个代码够实在、够接地气吧,哈哈哈

总结

快速幂算法最核心的部分就是判断指数的奇偶性和指数减半的操作,是要理解了这两点,快速幂就不难掌握了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值