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

在数学中,辗转相除法,又称欧几里得算法(英語:Euclidean algorithm),是求最大公约数的算法。

两个整数的最大公约数是能够同时整除它们的最大的正整数。

辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数相除余数的最大公约数。

例如,252105的最大公约数是21252=21*12;105=21*5);因为 252 − 105 = 21 × (12 − 5) = 147 ,所以147105的最大公约数也是21。在这个过程中,252较大的数缩小变成了147,但是他们的最大公约数在减法算术中是不会变化的,我们可以利用这个性质,在不知道公约数的情况下,不断缩小除数,所以继续进行同样的计算可以不断缩小这两个数直至其中一个变成零。这时,所剩下的还没有变成零的数就是两数的最大公约数。

由辗转相除法也可以推出,两数的最大公约数可以用两数的整数倍相加来表示,如 21 = 5 × 105 + (−2) × 252。这个重要的結論叫做貝祖定理。


正确性的证明

辗转相除法的正确性可以分成两步来证明。

  1. 在第一步,我們會證明算法的最终结果 r N − 1 r_{N−1} rN1 同时整除ab。因为它是一个公约数,所以必然小于或者等于最大公约数g
  2. 在第二步,我們證明g能整除 r N − 1 r_{N−1} rN1。所以g一定小于或等于 r N − 1 r_{N−1} rN1
  3. 两个不等式只在 r N − 1 r_{N−1} rN1=g时同时成立。

具体证明如下:

  1. 证明 r N − 1 r_{N−1} rN1同时整除a和b:
  • 因为余数 r N r_{N} rN是0, r N − 1 r_{N−1} rN1能够整除 r N − 2 r_{N−2} rN2
    r N − 2 r_{N−2} rN2= q N q_{N} qN r N − 1 r_{N−1} rN1
  • 因为 r N − 1 r_{N−1} rN1能够整除 r N − 2 r_{N−2} rN2,所以也能够整除 r N − 3 r_{N−3} rN3
    r N − 3 r_{N−3} rN3 = q N − 1 q_{N-1} qN1 r N − 2 r_{N−2} rN2 r N − 3 r_{N−3} rN3
  • 同理可证 r N − 1 r_{N−1} rN1可以整除所有之前步骤的余数,包括ab,即 r N − 1 r_{N−1} rN1ab的公约数, r N − 1 r_{N−1} rN1g
  1. 证明最大公约数g能整除rN-1:
  • 根据定义,ab可以写成g的倍数:a = mgb = ng,其中mn是自然数。因为 r 0 r_0 r0 = a − q 0 q_0 q0b = mg − q 0 q_0 q0ng = (m − q 0 q_0 q0n)g,所以g整除 r 0 r_0 r0。同理可证g整除每个余数 r 1 r_1 r1, r 2 r_2 r2, …, r N − 1 r_{N-1} rN1。因為最大公约数g整除 r N − 1 r_{N-1} rN1,因而g r N − 1 r_{N-1} rN1
    因为第一步的证明告诉我们 r N − 1 r_{N-1} rN1g,所以g = r 0 r_0 r0。即:

g = GCD(a, b) = GCD(b, r 0 r_0 r0) = GCD( r 0 r_0 r0, $r_1) = … = GCD( r N − 2 r_{N-2} rN2 , r N − 1 r_{N-1} rN1) = r N − 1 r_{N-1} rN1


代码实现

迭代版本:

int gcd(int m,int n)
{
        int t = 1;
        while(t != 0)
        {
                t=m%n;
                m=n;
                n=t;
        }
        return m;
}

递归版本:

int gcd(int n,int m)
{
        if(m==0)
                return n;
        else
                return gcd(m,n%m);
}


参考来源:
wikipedia - Euclidean algorithm

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值