欧几里得算法和扩展欧几里得算法

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

整数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,a\mod b) \tag{1} \]

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

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

\[ax^*+by^*=\gcd(b,a\mod b) \tag{3} \]

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

\[a\mod b = a-\lfloor a/b \rfloor b=a-kb ,\ k为一个非负整数 \tag{4} \]

由(3)(4)

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

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

由(2)(6)可以得到

\[x=y^* \\ y=x^*-ky^*=x^*- \lfloor a/b \rfloor 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));
}
posted @ 2020-05-19 12:14  li修远  阅读(222)  评论(0编辑  收藏  举报