Java实现快速幂算法详解

Java实现快速幂算法详解

快速幂算法(Power Mod)可用来求解形如$a^b\%c$的表达式,其中$a$、$b$和$c$均为正整数。快速幂算法可通过将$b$的二进制分解,以分治的方式加速幂数的计算。

算法流程

  1. 将幂数$b$转化为二进制数
  2. 遍历二进制数中每一位,从高位到低位,若该位上的二进制数字为1,则将当前幂数乘上底数$a$,否则幂数不变。
  3. 将所得的幂数对$c$取模,得到结果

实现代码

public static int powerMod(int a, int b, int c) {
    int res = 1;
    a = a % c;
    while (b > 0) {
        if ((b & 1) == 1) {
            res = (res * a) % c;
        }
        b >>= 1;
        a = (a * a) % c;
    }
    return res;
}

在代码中,a为底数,b为幂数,c为模数。首先将底数a对模数c取模,避免幂数过大导致计算过程中溢出。接下来进入循环,每次移位操作等价于将当前幂数除以2,检查其二进制位最低位。若该二进制位为1,则将结果乘上当前的底数,否则不变。随后将底数自乘,将幂数右移1位,重复上述步骤,直到幂数为0. 最后返回结果。

示例

下面通过两个示例说明快速幂算法的使用方法。

示例1

将$2^{10} \mod 5$的值计算出来。其中,$a=2,b=10,c=5$。

按照快速幂算法的步骤,将$10$转化为二进制数$1010$,从高位到低位遍历,结果为:

  • 当第一位为1时,取$2$本身,此时结果为$2$
  • 当第二位为0时,不变,此时结果为$2$
  • 当第三位为1时,取$2^4$的值,即$16$,对$5$取模后的结果为$1$
  • 当第四位为0时,不变,此时结果为$1$

最后得到$2^{10} \mod 5 = 1$

示例2

将$3^{456789} \mod 100$的值计算出来。其中,$a=3,b=456789,c=100$。

按照同样的步骤,将$456789$转化为二进制数$1110110011000110101$,从高位到低位遍历,结果为:

  • 当第一位为1时,取$3$本身,此时结果为$3$
  • 当第二位为0时,不变,此时结果为$3$
  • 当第三位为1时,取$3^4$的值,即$81$,对$100$取模后的结果为$81$
  • 当第四位为0时,不变,此时结果为$81$
  • 当第五位为1时,取$3^8$的值,即$6561$,对$100$取模后的结果为$61$
  • 当第六位为0时,不变,此时结果为$61$
  • 当第七位为0时,不变,此时结果为$61$
  • 当第八位为1时,取$3^{64}$的值,即$150094635296999121$,对$100$取模后的结果为$21$
  • 当第九位为1时,取$3^{128}$的值,即$4611686018427387904$,对$100$取模后的结果为$64$
  • 当第十位为1时,取$3^{256}$的值,即$1063873589237165248$,对$100$取模后的结果为$44$
  • 当第十一位为0时,不变,此时结果为$44$
  • 当第十二位为1时,取$3^{2048}$的值,即$3545029986111908895090048$,对$100$取模后的结果为$56$
  • 当第十三位为0时,不变,此时结果为$56$
  • 当第十四位为1时,取$3^{16384}$的值,即$655630285178720326763184923104$,对$100$取模后的结果为$36$
  • 当第十五位为0时,不变,此时结果为$36$
  • 当第十六位为1时,取$3^{131072}$的值,即$48661191875666868481...6432991824$,对$100$取模后的结果为$96$
  • 当第十七位为1时,取$3^{262144}$的值,即$23626472274681353693...9890982400$,对$100$取模后的结果为$16$
  • 当第十八位为0时,不变,此时结果为$16$
  • 当第十九位为1时,取$3^{524288}$的值,即$669381122094400496394...664339200$,对$100$取模后的结果为$96$
  • 当第二十位为1时,取$3^{1048576}$的值,即$44612008135508454900481531264...1$,对$100$取模后的结果为$36$
  • 当第二十一位为0时,不变,此时结果为$36$
  • 当第二十二位为1时,取$3^{2097152}$的值,即$55535850279941600865386...583003463424$,对$100$取模后的结果为$96$
  • 当第二十三位为0时,不变,此时结果为$96$
  • 当第二十四位为1时,取$3^{4194304}$的值,即$30880391046625326617429...489089563904$,对$100$取模后的结果为$56$
  • 当第二十五位为0时,不变,此时结果为$56$
  • 当第二十六位为1时,取$3^{8388608}$的值,即$89671244029286034209171382292444031916110...412652032$,对$100$取模后的结果为$16$
  • 当第二十七位为0时,不变,此时结果为$16$
  • 当第二十八位为1时,取$3^{16777216}$的值,即$804357544123133804235070328155150197684...465206784$,对$100$取模后的结果为$56$
  • 当第二十九位为1时,取$3^{33554432}$的值,即$5757218682652774236...5507520564736000$,对$100$取模后的结果为$96$
  • 当第三十位为0时,不变,此时结果为$96$
  • 当第三十一位为1时,取$3^{67108864}$的值,即$324518553658426726783589...665610765209600$,对$100$取模后的结果为$16$

最后得到$3^{456789} \mod 100 = 16$

结语

快速幂算法可以有效地解决大数求幂的问题,其时间复杂度为$O(logn)$,可以有效地减少计算时间。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现快速幂算法详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • JSP连接Access数据库

    JSP连接Access数据库的过程可以分为以下几个步骤: 1. 安装Access驱动程序 在JSP连接Access数据库之前需要先安装Microsoft Access数据库驱动程序,可以从Microsoft官网下载,并按照说明进行安装。 2. 导入Access数据库到项目中 在JSP项目中创建一个lib文件夹,将Microsoft Access数据库驱动程序…

    Java 2023年6月15日
    00
  • Spring MVC中自定义拦截器的实例讲解

    以下是关于“Spring MVC中自定义拦截器的实例讲解”的完整攻略,其中包含两个示例。 Spring MVC中自定义拦截器的实例讲解 拦截器是Spring MVC中的一个重要组件,它可以在请求到达Controller之前或之后执行一些操作。在本文中,我们将讲解如何在Spring MVC中自定义拦截器。 步骤一:创建Maven项目 打开IntJ IDEA,选…

    Java 2023年5月17日
    00
  • MyBatis框架之mybatis逆向工程自动生成代码

    MyBatis框架之mybatis逆向工程自动生成代码完整攻略 什么是逆向工程 逆向工程是指通过数据库的表结构自动生成Java代码的过程。在Web开发中,Java开发人员通常会和数据库打交道,而每次手写一个POJO类、DAO类和Mapper文件比较繁琐,如果能够快速地生成这些代码,开发效率可以得到显著提升。MyBatis框架提供了逆向工程工具用于自动生成Ja…

    Java 2023年5月20日
    00
  • Spring mvc AJAX技术实现原理解析

    Spring MVC AJAX技术实现原理解析 AJAX(Asynchronous JavaScript and XML)是一种用于创建快速动态Web页面的技术。在Spring MVC中,我们可以使用AJAX来实现异步请求和响应。本文将详细讲解Spring MVC AJAX技术的实现原理,并提供两个示例说明。 AJAX的实现原理 AJAX的实现原理是通过XM…

    Java 2023年5月17日
    00
  • JDK14性能管理工具之jstack使用介绍

    JDK14性能管理工具之jstack使用介绍 简介 jstack 是 JDK 自带的一款性能分析工具,可以用来查看 Java 进程中每个线程的状态、堆栈信息等,来帮助我们定位问题并进行性能分析。 jstack 命令语法 jstack 的使用非常简单,语法如下: jstack [ option ] <pid> 其中,option 表示可选参数, 表…

    Java 2023年5月26日
    00
  • 优化spring boot应用后6s内启动内存减半

    优化 Spring Boot 应用可以显著降低应用启动进程所需的时间,同时减少内存占用,提高应用的性能。下面是优化 Spring Boot 应用的完整攻略: 1. 去除无用依赖 在应用启动过程中,Spring Boot 会扫描所有的依赖并生成一个应用的依赖关系树。因此,需要仅仅保留应用的所需依赖,去除无用依赖,减小应用的依赖树,加速应用的启动时间。 可以通过…

    Java 2023年6月3日
    00
  • Java中多态性的实现方式

    Java中的多态性是指同一个方法或对象,在不同情境下表现出不同的形态。常见的实现方式有以下两种: 1. 方法重写(Override) 方法重写指子类中重新定义一个父类已有的方法,并按照子类的需求来实现该方法。方法重写是利用多态的最常用方式之一。 在Java中实现方法重写,需要满足以下条件: 方法名和参数列表与父类中该方法一致 访问修饰符不能低于父类的该方法 …

    Java 2023年5月18日
    00
  • Spring+SpringMVC+MyBatis整合详细教程(SSM)

    以下是关于“Spring+SpringMVC+MyBatis整合详细教程(SSM)”的完整攻略,其中包含两个示例。 1. 前言 Spring+SpringMVC+MyBatis整合(简称SSM)是一种常用的Java Web开发框架,它将Spring、SpringMVC和MyBatis三个框架整合在一起,提供了一种灵活的方式来开发Web应用程序。本攻略将详细讲…

    Java 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部