zoukankan      html  css  js  c++  java
  • 欧几里得算法和扩展欧几里得算法

    欧几里得算法(辗转相除法)

    整数a整数b的最大公约数。

    int gcd(int a, int b) {
        if(a < b) {
            return gcd(b,a);
        }
        return b== 0 ? a : gcd(b, a%b); 
    }
    

    扩展欧几里得算法是欧几里得算法的扩展。除了计算ab两个整数的,此算法还能找到整数xy(其中一个很可能是负数)。给与正整数a,b必然有整数xy使得ax+by=gcd(a,b)。辗转相除法,可得最大公约数。然后,收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的整数解。

    由欧几里得算法,可知有(1)

    [gcd(a,b) = gcd(b,amod b) ag{1} ]

    由裴蜀定理,一定有(2)(3)

    [ax+by=gcd(a,b) ag{2} ]

    [ax^*+by^*=gcd(b,amod b) ag{3} ]

    根据x*y*推出xy的值。

    [amod b = a-lfloor a/b floor b=a-kb , k为一个非负整数 ag{4} ]

    由(3)(4)

    [ax^*+by^*= gcd(b,amod d) = bx^*+(a mod b)y^*= bx^*+(a -kb)y^* ag{5} ]

    [bx^*+(a -kb)y^*=bx^*+ay^*-kby^*=ay^*+b(x^*-ky^*) ag{6} ]

    由(2)(6)可以得到

    [x=y^* \ y=x^*-ky^*=x^*- lfloor a/b floor y^* ]

    代码java实现:

    public static int[] exGcd(int a, int b, int[] gxy) {
        if(b == 0) 
            return new int[] {a,1,0};
        
        gxy = exGcd(b, a%b, gxy);
        int gcd = gxy[0], _x = gxy[1], _y = gxy[2];//收集gcd(b,a%b), x*,y*
        int x = _y, y = _x-(a/b)*_y;//根据x*,y*反推x,y
        return new int[] {gcd, x, y};
    }
    public static void main(String[] args) {
        int[] gxy = new int[3];//空数组,用于返回 gcd(a,b), x,y三个值
        gxy = exGcd(16,100,gxy);
        System.out.println(Arrays.toString(gxy));
    }
    
  • 相关阅读:
    [译]Java例解Interface
    【笔记】2014-01至2014-02
    【笔记】2013-12
    【笔记】2013-10至2013-11
    【笔记】2013-09
    【笔记】2013-08
    【笔记】2013-07
    生活工作中好用的快捷键和小工具(更新)
    Android Studio更新Gradle问题
    gradle构建spring5源码
  • 原文地址:https://www.cnblogs.com/lixyuan/p/12916166.html
Copyright © 2011-2022 走看看