欧几里得算法(辗转相除法)
求正整数a
和正整数b
的最大公约数。
int gcd(int a, int b) {
if(a < b) {
return gcd(b,a);
}
return b== 0 ? a : gcd(b, a%b);
}
扩展欧几里得算法是欧几里得算法的扩展。除了计算a
、b
两个整数的,此算法还能找到整数x
、y
(其中一个很可能是负数)。给与正整数a
,b
必然有整数x
与y
使得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*
推出x
和y
的值。
[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));
}