引言
我们知道,求最大公约数可以用欧几里德方法。d = gcd(a, b) = gcd(b, a%b)。
那么我们是否可以快速求出以下等式的系数x和y呢?
d = gcd(a,b) = x*a + y*b
(注:系数x和y是唯一的。参见introduction to algorithm中的number theory章节)
问题
给出两个整数,求其最大公约数以及唯一的系数。即:
d = gcd(a,b) = x*a + y*b,给定a,b,求(d, x, y).
基本迭代关系
d = gcd(a, b) = x * a + y * b
d' = gcd(b, a%b) = x' * b + y' * (a%b) = x' * a + y' * (a - (a/b)*b) = y' * a + (x' - (a/b)y') * b
d = d'
==>
(d, a, b) = (d', y', x' - y'*(a/b))
(边界条件是b=0是,返回(a, 1, 0)
代码
#!/usr/bin/env python import sys def euclid(a, b): if b==0: return a else: return euclid(b, a%b) def gcd(a, b): a = abs(a) b = abs(b) return euclid(a, b) # extended euclid algorithm # d = gcd(a,b) = xa+yb # get gcd and the coefficients def extended_euclid(a, b): if b==0: return (a, 1, 0) (d_low, x_low, y_low) = extended_euclid(b, a%b); (d, x, y) = (d_low, y_low, x_low - a/b*y_low); return (d, x, y) def gcd2(a, b): a = abs(a) b = abs(b) return extended_euclid(a, b) if __name__ == '__main__': if len(sys.argv) != 3: print 'gcd.py num1 num2' sys.exit(1) else: num1 = int(sys.argv[1]) num2 = int(sys.argv[2]) (d, x, y) = gcd2(num1, num2) print '%d = gcd(%d,%d) = %d*%d + %d*%d'% \ (d, num1, num2, x, num1, y, num2)
测试示例
./gcd.py 27 21
3 = gcd(27,21) = -3*27 + 4*21
./gcd.py 567432 3892347
27 = gcd(567432,3892347) = 20078*567432 + -2927*3892347