快速幂取模算法

来源:互联网 发布:天行健君电子商务软件 编辑:程序博客网 时间:2024/06/18 12:37

当我们计算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);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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

参考文献:http://blog.csdn.net/quinnnorris/article/details/77587096

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小兔子穿的衣服 多肉植物小兔子怎么养 小兔子外卖单 疯狂小兔子 小兔子为什么会叫 小兔子的外形特点 小兔兔乖乖 一根长气球制作小兔子 梦见小兔崽是什么意思 小兔崽子是什么意思 小兔小兔轻轻跳 小全张 张行长全篇 张行长与妻子全文阅读全 张行长全篇在线阅读 一jie鲁夫全24张顺序图 把妻子献给张行长全目录 男模张叶全见 小八义评书 刘兰芳评书小八义 二人转小帽绣八仙 小八爪 二个小八路 小八路的故事 两个小八路的读后感 铁血八路 快乐小胖 小四郎 七郎八虎 小公主简笔画 公主从小含玉棒 小公主跟我回家吧 聊天小公主 祝宝贝小公主生日感动祝福 小公主车图片 小公主车 小公主英语 小公主汽车 小公主莎拉 小公主苏 打扮小公主 小公主涂色