快速幂取模算法的引入是从大数的小数取模的朴素算法的局限性所提出的,在朴素的方法中我们计算一个数比如5^1003%31是非常消耗我们的计算资源的,在整个计算过程中最麻烦的就是我们的5^1003这个过程

缺点1:在我们在之后计算指数的过程中,计算的数字不都拿得增大,非常的占用我们的计算资源(主要是时间,还有空间)

缺点2:我们计算的中间过程数字大的恐怖,我们现有的计算机是没有办法记录这么长的数据的,所以说我们必须要想一个更加高效的方法来解决这个问题

当我们计算AB%C的时候,最便捷的方法就是调用Math函数中的pow方法,但是有时A的B次方数字过大,即使是双精度的double也会溢出,这个时候为了得到AB%C的结果,我们会选择使用快速幂取模算法,简单快速的得到我们想要的结果。

为了防止数字溢出并且降低复杂度,我们需要用到下面的公式:

ab mod c = (a mod c)b mod c

这个公式的意思就是:积的取余等于取余的积的取余。很容易看出来这个公式是具有传递性的,这样我们可以通过不断的取余让a越来越小,防止出现溢出的情况。

理论上,有了这个公式我们就可以写代码了,通过不断的对a进行取模保证结果不会溢出,这确实能计算出较大次方的幂的模,但是这种方法的复杂度仍旧是O(N),并不快速。

为了更快速的计算出幂的模,我们还要依赖下面这个公式:

ab mod c = (a2)b/2 mod c , b为偶数 
ab mod c = ((a2)b/2·a) mod c , b为奇数

这个公式很简单,原理就是不断的用a的平方来代替b,将b替换为原来的一半。因为我们通过第一个公式知道了一个数的模的相同次方的模相同(这句话说的有点绕,就是公式一的意思)。那么我们用a*a%c的结果来代替a效果是一样的。

所以根据上述的公式,我们得到复杂度O(logN)这样的计算快速幂的方法:

import java.util.Scanner;

public class Main {

 public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = in.nextInt(), b = in.nextInt(), c = in.nextInt();
int res = 1;
a %= c;
for (; b != 0; b /= 2) {
if (b % 2 == 1)
res = (res * a) % c;
a = (a * a) % c;
}
System.out.println(res);
}
}

案例:

题目描述

给定a和b,输出a^b的最后一个数字。

输入格式

输入数据有多组,每组数据占一行,每行为a和b的值(0 < = a,b < = 2^30)。

输出格式

对每组输入数据,输出a^b的最后一位数字,每组数据占一行。

输入样例 复制

2 2
3 4

输出样例 复制

4
1

上述的问题就可以用  下面的代码解决 ,思路就是  a^b%10 取最后一位

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
Scanner cin = new Scanner(System.in); while(cin.hasNext()){
int a = cin.nextInt();
int b = cin.nextInt();
if(a<0||b<0){
return;
}
System.out.println(getResult(a, b)); } } public static int getResult(int a,int b){
int res = 1;
int c = 10;
a %= c;
for (; b != 0; b /= 2) {
if (b % 2 == 1)
res = (res * a) % c;
a = (a * a) % c;
}
return res;
}
}

这个算法大概如此,第一步先a%=c是为了将a缩小一些,防止在for中第一次进行a*a的时候数字溢出。在for循环中,如果是b为奇数则令res=res*a,直接先将a乘到结果中去,最后做处理,又是为了防止数字溢出直接将res*a的结果mod c操作。这个for循环中,早晚有一天b会等于1,进入if分支,最后将res的值计算完毕mod c退出for循环,的到最后的结果。

转自:https://www.jb51.net/article/129333.htm

《Java语言实现快速幂取模》的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. Number()、parseInt()和parseFloat()的区别

    JS中Number().parseInt()和parseFloat()的区别 三者的作用: Number(): 可以用于任何数据类型转换成数值: parseInt(): 函数可解析一个字符串,并返回一 ...

  2. ubuntu下安装go环境

    1.官网下载go语言安装包 地址:https://studygolang.com/dl 2.服务器上安装go 将下载下来的安装包解压到/usr/local下 tar xf go1.12.1.linux ...

  3. elk-filebeat-(效果图示)(四)

    一.vim filebeat-6.3.2-linux-x86_64/filebeat.yml - type: log # Change to true to enable this input con ...

  4. HTML、CSS知识点,面试开发都会需要--No.1 HTML

    No.1   HTML 1.网页结构 网页结构一般都包含文档声明DOCTYPE,并且在head中的meta应该包含编码格式.关键字.网页描述信息.简单格式如下: <!DOCTYPE html&g ...

  5. Prometheus监控学习记录

    官方文档 Prometheus基础文档 从零开始:Prometheus 进阶之路:Prometheus —— 技巧篇 进阶之路:Prometheus —— 理解篇 prometheus的数据类型介绍 ...

  6. Gym 101194C / UVALive 7899 - Mr. Panda and Strips - [set][2016 EC-Final Problem C]

    题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?opti ...

  7. C0气体传感器分析

    1.外观.价格 2.工作原理 MQ-7 CO气体传感器使用的敏感元件为气敏材料(SnO2),该传感器对一氧化碳的灵敏度高. SnO2在洁净空气中电导率低,传感器的电导率随着空气中CO气体浓度增加而增大 ...

  8. XSS笔记

    XSS测试代码: <img src="javascript:alert(/xss/)"> <script src=http://evil.com/xss.js&g ...

  9. 7.1-uC/OS-III中断管理

    在 uC/OS 系统中,中断相当于一个优先级最高的任务.中断一般用于处理比较紧急的事件, 而且只做简单处理,例如标记该事件,带退出中断后再做详细处理.在使用 uC/OS系统时, 一般建议使用信号量. ...

  10. (转)spring中的拦截器(HandlerInterceptor+MethodInterceptor)

    1.  过滤器跟拦截器的区别 在说拦截器之前,不得不说一下过滤器,有时候往往被这两个词搞的头大. 其实我们最先接触的就是过滤器,还记得web.xml中配置的<filter>吗~ 你应该知道 ...