zoukankan      html  css  js  c++  java
  • 让你秒懂的快速幂入门教程

    让你秒懂的快速幂入门教程

    我们先来看一个例子:如何计算(2^8)

    首先,你会想到直接把(8)(2)乘起来,像这样:

    [egin{aligned} 2*2&=4 \ 4*2&=8 \ 8*2&=16 \ 16*2&=32 \ 32*2&=64 \ 64*2&=128 \ 128*2&=256 end{aligned} ]

    这样需要做7次乘法运算。有没有更快的做法呢?其实还可以这样:

    [2^2=4 \ 4^2=16=(2^2)^2=2^{2*2}=2^4 \ 16^2=256=(2^4)^2=2^{2*2*2}=2^8 ]

    上面的过程可以形象地理解为:

    这样只需要做3次乘法运算,就能算出(2^8)的值!

    上面这个例子揭示了快速幂算法的核心思想。即,要运算一个数(a)(2^n)次方,可以将其自乘(n)次,每次指数都会翻倍,这样能够快速算得(a^{2^n})的值。用c++写起来就是这样:

    int a=2,n=8;
    n=log2(n); //log2()函数定义中头文件<cmath>中,表示以2为底取对数
    for(int i=1;i<=n;++i){
        a=a*a;
    }
    

    那你可能想问了,如果幂指数不是(2)的整数次方,该如何计算呢?以(2^7)为例:

    我们只要把指数(7)化为几个(2)的整数次方之和((2^2+2^1+2^0)),再将对应的(2^{2^2},2^{2^1},2^{2^0})乘起来,就能得到(2^7)

    看到这里,机智的你可能发现了什么:把一个十进制数化为几个2的整数次方之和,这不就是进制转换的过程吗?

    [(7)_{10}=(111)_{2} \ 7=2^2+2^1+2^0 ]

    二进制,正是计算机最擅长的东西。c++中有&和>>运算符,是针对二进制数进行运算的。

    a&b得到a与b按位与的结果,如果将一个数&1,由于1除了末位其余位都是0,与的结果也是0,那么只需考虑末位,如果这个数的末位为1,得到的就是1;如果这个数末位是0,得到的就是0。我们可以用这个方法来判断一个数的二进制末位是否为1。

    a>>b得到将数a的二进制都向右移动b位。可以类比十进制,向右移动一位(也就是小数点向左移动一位)表示将这个数除10,二进制中右移一位就是除2。

    int quick_power(int a,int n){
        int ans=1;  //ans要初始化为1
        while(n){   //当n不为0时继续进行快速幂
            if(n&1){    //若n的二进制末位为1则返回真
                //如果n的二进制数第i位为1,说明将幂指数n分解之后会包含2^i
                //因此需要将当前计算的a^(2^i)乘进答案
                ans=ans*a;
            }
            n>>=1; //表示将二进制数n左移一位,舍弃最低位
            a=a*a; //计算a^(2^i)
        }
        return ans;
    }
    
  • 相关阅读:
    Tomcat8 配置Oracle11g数据源
    通过代码设置 为横屏
    HttpClient4.3.6 实现https访问
    创建mysql数据库
    设置android状态栏颜色和toolbar颜色一致
    定义任务打印gradle下载的jar包位置
    修改weblogic jvm启动参数
    android.support.v7.widget.Toolbar 中menu图标不显示问题
    android.support.design.widget.AppBarLayout 在android5.0+底部显示空白条问题
    浅析jQuery框架与构造对象
  • 原文地址:https://www.cnblogs.com/1024th/p/11203562.html
Copyright © 2011-2022 走看看