快速幂取模算法

来源:互联网 发布:仪表总里程算法 编辑:程序博客网 时间:2024/06/15 09:54

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

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 药品批号查询网 如何查药品的真假 药品电子监管码查询网 医保药品目录查询 怎样查询药品真伪 药品电子码查询 药品监管码查询扫描 药品准字号查询 进口药品真伪查询 如何查询药品真假 怎样查询药品电子监管码 药品报销 如何查询药品电子监管码 怎么查询药品电子监管码 医保药品查询 医院药品查询 查莉娅 查血糖挂什么科 查血糖多少钱 查血糖 查血糖前一天注意事项 查血糖怎么查 怎么查血糖高不高 查空腹血糖 血糖高查什么项目 怎么查血糖高 怎样查血糖 什么时候查血糖 查空腹血糖能喝水吗 查血糖前一天晚上饮食禁忌 医院查血糖多少钱 查血糖主要是查什么 查血糖挂什么科室 孕妇血糖怎么查 空腹查血糖可以喝水吗 孕妇查血糖多少钱 测血糖多少钱 血糖怎么测量 血糖怎么测 查血糖的注意事项 测血糖的方法