zoukankan      html  css  js  c++  java
  • 快速幂

    求x^m 一般方法是 xm = x * xm-1,这样需要做m次乘法,未免过慢。

    加速方法有两种。

    1.基于当m为偶数时, xm = (x2)^(m/2) ;当m为奇数时, xm = x * xm-1。显然当m为偶数时m会减半,当m为奇数时,下次就是偶数。m可以很快收敛到0.(^表示幂)

    2.将m看成二进制串mkmk-1...m1m0,那么xm = xm0*2^0 + m1*2^1 + ... + mk*2^k = xm0*2^0 * xm1*2^1 * ... * xmk*2^k.  mi为0或1,假设平均有一半mi为1,即k个,那么总共才只需要做(k+(k/2))次乘法。

    下面给出代码。第一个方法是加速方法1,第二个方法是加速方法1的迭代形式,第三个方法是加速方法2。

    在网上看到有人将 *2 或 /2,改为移位运算,就说效率更高。这其实是扯谈。连我们都知道移位运算效率高,*2 和 /2 就是一个相当于移位运算的操作,做编译器的人会不知道?即使你写成 *2 或 /2,编译器也会帮你优化为移位运算。不相信的同学可以用C语言测试一下,只需将代码编译成汇编代码看看是否一样。

    public class pow{
        public static int fastExp(int x, int m){
            if(m == 0)return 1;
            if(m % 2 == 0){
                //x^m = (x^2)^(m/2)
                return fastExp(x*x, m/2);
            }
            else{
                //x^m = x * x(m-1)
                return x * fastExp(x, m-1);
            }
        }
        public static int fastExp_iter(int x, int m){
            int result  = 1;
            while(m != 0){
                if(m % 2 == 0){
                    x *= x;
                    m /= 2;
                }
                else{
                    result *= x;
                    m --;
                }
            }
            return result;
        }
        public static int fastExpBin(int x, int m){
            //x^m = x^(m0 * 2^0) * x^(m1 * 2^1) * x^(m2 * 2^2) * ... * x^(mk * 2^k)
            int result  = 1;
            while(m != 0){
                if((m&1) == 1){
                    //m0 = 1
                    result *= x;
                }
                //x对应每一位mi
                x *= x;
                m >>= 1;
            }
            return result;
        }
        public static void main(String[] args){
            for (int i = 0; i < 10; i ++)
                System.out.print(fastExp(2, i) + " ");
            System.out.println();
            
            for (int i = 0; i < 10; i ++)
                System.out.print(fastExp_iter(2, i) + " ");
            System.out.println();
    
            for (int i = 0; i < 10; i ++)
                System.out.print(fastExpBin(2, i) + " ");
            System.out.println();
        }
    }
    Java
  • 相关阅读:
    Abp Swagger API中文说明配置方法
    ABP框架中使用MySQL数据库
    windows + jenkins + .net core + iis自动化部署新手入门
    在图片上画矩形框
    base64转换成np、opencv、PIL
    RankSVM
    tf.placeholde函数解释与用法
    slim.arg_scope()的使用
    SSD网络结构
    tensorflow学习笔记
  • 原文地址:https://www.cnblogs.com/7hat/p/3387267.html
Copyright © 2011-2022 走看看