先来看看欧几里得算法:

 1 public class Gcd {
 2     /**
 3      * 欧几里德算法,即辗转相除法 最大公约数
 4      */
 5     public static long gcd(long m, long n) {
 6         return n == 0 ? m : gcd(n, m % n);
 7     }
 8
 9     /**
10      * 最小公倍数lowest common multiple (LCM)
11      * 最小公倍数 = a * b / a和b的最大公约数
12      */
13     private static long lcm(long a, long b) {
14         return a * b / gcd(a, b);
15     }
16 }

  接着再来看裴蜀(贝祖)等式:对于任何整数a、b和它们的最大公约数d,关于未知数x和y的线性丢番图方程(称为裴蜀等式):ax+by = m 有整数解时当且仅当m是d的倍数。x、y可用扩展欧几里得算法求得。特别地,方程ax+by=1 有整数解当且仅当整数a和b互质。

  那什么是扩展欧几里得算法呢?

  现在我们知道了 a 和 b 的最大公约数是 gcd(a,b) 后面用gcd表示 ,那么,我们一定能够找到这样的 x 和 y ,使得: a*x + b*y = gcd 。这是一个不定方程。那么,怎么求出这个特解 x 和 y 呢?只需要在欧几里德算法的基础上加点改动就行了。我们观察到:欧几里德算法停止的状态是: a= gcd , b = 0 ,那么,这是否能给我们求解 x y 提供一种思路呢?

  首先,将a=gcd,b=0代入原方程,得到gcd*x+0*y=gcd。那么,这时候,只要x = 1 ,y 是 0 或者其他值(无所谓是多少,反正任何数乘以 0 都等于 0, 但是 x 一定要是 1),这时,我们就会有: a*1 + b*0 = gcd。 当然这是最终状态,但是我们是否可以从最终状态反推到最初的状态呢?

  假设当前我们要处理的是求出 a 和 b的最大公约数,并求出 x 和 y 使得 a*x + b*y= gcd ,而我们已经求出了下一个状态:b 和 a%b 的最大公约数,并且求出了一组x1 和y1 使得: b*x1 + (a%b)*y1 = gcd , 那么这两个相邻的状态之间是否存在一种关系呢?

  首先a可以表示成 a = b*t + k,而 t = a/b(这里的 “/” 指的是整除),k = a%b ,所以 可以得到a = b*(a/b) +k  -->  k=a-(a/b)*b  -->  a%b = a - (a/b)*b,代入 b*x1 + (a%b)*y1 = gcd。

  那么,我们可以进一步得到:gcd = b*x1 + (a-(a/b)*b)*y1
                   = b*x1 + a*y1 – (a/b)*b*y1
                   = a*y1 + b*(x1 – a/b*y1)

 对比之前我们的状态:求一组 x 和 y 使得:a*x + b*y = gcd ,是否发现了什么?

 这里: x = y1

   y = x1 – a/b*y1

  现在我们找到一组特殊的解  x0 和 y0,那么,我们就可以用 x0 和 y0 表示出整个不定方程的通解:

     x = x0 + (b/gcd)*t  ( t 取任意整数)

  y = y0 – (a/gcd)*t

  如果我们想要得到 x 大于 0 的第一个解的话,那么表达式就是:

    b /= d

    x = ( x0%b + b) % b

 以上就是扩展欧几里德算法的全部过程,依然用递归写:

 1 public class ExtGcd {
 2     static long x;
 3     static long y;
 4
 5     public static long gcd(long m, long n) {
 6         return n == 0 ? m : gcd(n, m % n);
 7     }
 8     /**
 9      * 扩展欧几里得
10      * 调用完成后 静态变量xy是ax+by=m的解
11      * 返回的还是最大公约数
12      */
13     public static long ext_gcd(long a,long b){
14         if (b==0) { // 求出了最大公约数 为a
15             x = 1;
16             y = 0;
17             return a;
18         }
19         long res = ext_gcd(b, a % b);
20         //x,y已经被下一层递归更新了
21         long x1 = x;//备份x
22         x = y;//更新x
23         y = x1 - a / b * y;//更新y
24         return res;
25     }
26     public static void main(String[] args) {
27         System.out.println(ext_gcd(2, 7));  // 1
28         System.out.println(x+" "+y);        // -3 1
29     }
30 }

  最后再来看一下这个线性方程(或者叫二元一次不定方程):ax+by = m 。有整数解时当且仅当m是gcd的倍数

  public static long linearEquation(long a, long b, long m) throws Exception {long d = ext_gcd(a, b);//m不是gcd(a,b)的倍数,这个方程无解if (m % d != 0) {throw new Exception("无解");}long n = m / d;//约一下,考虑m是d的倍数x *= n;y *= n;return d;}

  扩展欧几里德算法的应用主要有以下两个方面:

   (1)求解不定方程;

   (2)求解模线性方程(线性同余方程)与逆元;

转载于:https://www.cnblogs.com/xiaoyh/p/10331666.html

欧几里得算法及其扩展相关推荐

  1. 欧几里得算法、扩展欧几里得算法(特解、应用、通解)

    文章目录 1. 欧几里得算法(也叫辗转相除法) 1.1 直接上模拟 1.2 几何理解 1.3 用代数方法证明 g c d ( a , b ) = g c d ( b , a % b ) gcd(a, ...

  2. 扩展欧几里得算法_扩展欧几里得递推算法

    欧几里得算法 表示 整数 a 与 b 的最大公约数. 若 t = a % b, 则 证明略. 递推版 gcd 算法 gcd 接受变量元组 (a, b) 作为输入,输出最大公约数 (r). 我们很难直接 ...

  3. 欧几里得算法及扩展欧几里得算法简单解释

    欧几里得算法: 解释:给定两个自然数,求出两个自然数的最大公约数.也叫--辗转相除法 过程:1.给定两个自然数a.b 2.a == 0 时 gcd(a,b)= b:b == 0 时 gcd(a,b) ...

  4. 欧几里得算法及其扩展欧几里得算法——数论

    欧几里得算法(gcd):   又名辗转相除法,是求最大公约数的算法.辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数的差的最大公约数.两个数的最大公约数通常写成 gcd(a, b). ...

  5. 欧几里得算法(扩展欧几里得、欧拉定理、费马小定理)

    问题描述: a 和 b的最大公约数是多少? 古代解法:辗转相除法 迭代过程:例如: {a = 15 和 b = 12  } =>{ a = 12,b =  15 - (15/12)* 12 = ...

  6. 扩展欧几里得算法java_扩展欧几里得算法

    首先.扩展欧几里得定理:对于两个不全为0的整数a.b,必存在一组解x,y,使得ax+by==gcd(a,b); int gcd(int a,intb) {intt,d;if(b==0) { x=1; ...

  7. 欧几里得算法及扩展欧几里得

    long long gcd (long long a, long long h) {if (b == 0) return a;return gcd (b , a % b); } 这里求得的x是一个特解 ...

  8. 『扩展欧几里得算法 Extended Euclid』

    Euclid算法(gcd) 在学习扩展欧几里得算法之前,当然要复习一下欧几里得算法啦. 众所周知,欧几里得算法又称gcd算法,辗转相除法,可以在\(O(log_2b)\)时间内求解\((a,b)\)( ...

  9. 数论:欧几里得与扩展欧几里得算法

    文章目录 欧几里得算法 历史发展 表示 证明 代码 例题 扩展欧几里得算法 表示 求解方法 代码 其他定理: 例题 欧几里得算法 历史发展 欧几里得算法用来求得两个数的最大公约数,大约公元前300年首 ...

最新文章

  1. 多个so中模板单例的多次实例化
  2. 用户被忽悠 微软黑屏计划推至21日0点实施
  3. Linuxday01基础命令
  4. php多态性和继承是什么意思,封装 继承 多态的区别
  5. U盘在Ubuntu20.04下只能读取文件不能向U盘复制文件
  6. webpack打包后引用cdn的js_手摸手 Webpack 多入口配置实践
  7. css的position中absolute和fixed的区别
  8. hashmap put过程_阿里面试官:HashMap数据结构之道
  9. python 自动抢红包_用二十行代码实现微信自动抢红包
  10. data为long 怎么设置vue_vue.js入门
  11. 宏杉科技摆“擂台”,遍寻天下存储技术高手
  12. win10计算机策略组在哪,win10家庭版的组策略在哪里打开
  13. 结构光三维重建阶段性总结
  14. 初次使用Chloe(本人小白)
  15. Python入门(10)——宝可梦数据集探索
  16. 计算机价格谈判议程,谈判议程
  17. 如何防止form表单的重复提交
  18. ✖ 48 problems (48 errors, 0 warnings) 45 errors and 0 warnings potentially fixable with the `--fix
  19. 第8章 IP代理使用技巧与实战(8.1 结合Requests库使用IP代理)
  20. 王者荣耀与英雄联盟:如何解决玩家骂人的问题?

热门文章

  1. python opencv创建图像_OpenCV-Python 展示图像(1)
  2. 两台linux之间互传php脚本,linux下两台服务器实现同步的方法
  3. java 异步调用方法_乐字节Java编程之方法、调用、重载、递归
  4. datasnap ajax jsonp,有没有办法在Delphi DataSnap REST服务器上使用JSONP?
  5. 智能车的转弯部分_江西智能搬运平板车铁路轨道运输车-厂家直销
  6. LeetCode 1665. 完成所有任务的最少初始能量(贪心)
  7. LeetCode 764. 最大加号标志(DP)
  8. LeetCode 第 186 场周赛(1060/3107,前34.1%)
  9. 程序员面试金典 - 面试题 16.26. 计算器(栈)
  10. 程序员面试金典 - 面试题 01.06. 字符串压缩(字符串)