最大公约数问题(扩展)

引言

我们知道,求最大公约数可以用欧几里德方法。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

转载于:https://my.oschina.net/u/158589/blog/101568

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值