zoukankan      html  css  js  c++  java
  • 欧几里得算法(辗转相除求最大公约数)、更相减损术求余,我好像通俗地理解了辗转相除法和更相减损术。

    辗转相除法

     

    %是求余的意思

    抽象例子

    比如 a 和 b(a > b)

      a % b = r;

    如果r 不等于 0

      b % r = r1

    如果r1 不等于0

      r % r1 = r2

    如果r2 等于 0

      则r1就是最大公约数

    如果r2 不等于 0

    一直循环到 r_n为0   (r_n 最后一定可以是0,这个很好理解,往下看实例)

    最后r_n-1就是最大公约数

    具体例子

    比如 104 和 40

    104 % 40 = 24

    40 % 24 = 16

    24 % 16 = 8;

    16 % 8 = 0;

    所以得出104 和 40 的最大公约数就是 8

     

    原理阐述

    首先,任何两个数都会有最大公约数 (特殊情况下,最大公约数和最小公约数相等 ,都等于1)

    104 和 40 都是「最大公约数」的「倍数」

    两个数都是(倍数 X 最大公约数)这样的形式

    具体一点就是 k1*c % k2*c  = r  (c 代表最大公约数  r代表余数  k1、k2代表整数倍)

    那么求余的本质是什么?

    104 % 40 = 24

    就是104 里 包含多少个 整数倍的 40 ,减掉后剩下的余数

    所以 104 % 40 = 104 - 2x40 = 24

    公式化一点就是,k1*c - k2*c = r  (所以 r 也是c的倍数 r = k3*c,因为「c的倍数」- 「c的倍数」依然是「c的倍数」)

    然后这个 c 肯定是存在的,如果这个 r = kn*c 中的 kn 为1,那么 r = c 那么就可以求出最大公约数c了 

    那怎么把 kn 变成1 ????

    k1*c - k2*c = r = k3*c

    上面公式的本质,可以理解为 k1 % k2 = k3  (k1 > k2 > k3)

    如果我们一直拿两个小的不断进行求余,最后的 kn 一定可以是1

    为什么kn 最后一定可以是1

    比如 13 和 5 的求余

    13 % 5 = 3

    5 % 3 = 2

    3 % 2 = 1

    2 %1 = 0

    因为 (不断拿两个小的数的)求余过程中两个数会越来越小,肯定会有两个数只相差 1 的情况,也就是说kn一定有可能是1

    当余数为0时,说明有数对1进行了求余,此时kn就是1了

     

    所以就有了下面的

     

    104(13 X 8)  % 40(5 X 8) = 24(3 X8)

     40(5 X 8) % 24(3 X8) = 16(2 X8)

     24(3 X8) % 16(2 X8) = 8(1 x 8)

    16(2 X8) %  8(1 x 8) = 0(0 X 8)

     

    注意:

      我们什么时候知道 r = 1*c ?

      做到 24(3 X8) % 16(2 X8) = 8(1 x 8) 时

      我们并不知道 8 已经是 (1 X 8)了,

      其实我们要多做1步 16(2 X8) %  8(1 x 8) = 0(0 X 8)

      当求到余数为0的时候,就说明后面那一个 8一定是(1 X 8)

      因为任何数对1求余都会是0

       所以 8 就是最大公约数

     

    更相减损术

    抽象例子

    比如求 a 和 b 之间的最大公约数  (a  > b )

    a - b = s1  (a >b,a>s1)

    分3种情况进行下一步

    如果 b > s1

      b - s1 = s2  (b > s1.b>s2)

      接着重复,将后面两个小的数字相减,

      一直到sn为0,sn-1就是最大公约数

    如果 b < s1

      s1 - b = s2

      接着重复,将后面两个小的数字相减,

      一直到sn为0,sn-1就是最大公约数

    ‘如果 b = s1

      则最大公约数为s1

     

    具体例子

    104 和 40

    104 - 40 = 64

    64 - 40 = 24 

    40 - 24 = 16

    24 - 16 = 8

    16 - 8 = 8

    8 - 8 = 0

    所以得到 8 就是最大公约数

     

    原理阐述

    同样的104 和 40 一定有最大公约数

    具体一点就是 k1*c - k2 *c = s  (c为最大公约数,k1、k2是整数倍、s是差的结果)

    所以s = k3*c  (「c的倍数」- 「c的倍数」依然是「c的倍数」)

    同样地,我们将kn变成1,最后的 s 就等于 1*c,就是最大公约数

     

    那么如何将kn 变成1 ????

    下面就是更相减损的操作

    只要我们拿两个小的一直相减,结果kn肯定会有等于1的情况

    比如 13 和 5

    13 - 5 = 8

    8 - 5 = 3

    5 - 3 = 2

    3 - 2 = 1

    2 - 1 = 1

    1 - 1 = 0

    这个(不断拿两个小的数相减)的过程,实际上就是一种找1的过程

    找到最后,一定会出现 2 -  1 =  1,然后 1 -1 =0,这时就找到1了

    于是有了下面的 

    104(13*8) - 40(5*8) = 64(8*8)

    64(8*8) - 40(5*8) = 24 (3*8)

    40(5*8) - 24(3*8) = 16(2*8)

    24(3*8) - 16(2*8) = 8(1*8)

    16(2*8) - 8(1*8) = 8(1*8)

    8(1*8) - 8(1*8) = 0(0*8)

    注意:

      我们什么时候能够确定 s = 1*c ?

      当kn-1*c -  kn*c = 0时, kn-1*c = kn*c  

      也就是上一个减法已经是2-1 = 1了

      到它们相等时,它们不能再往下分了

      所以kn-1 = kn = 1  

      即8(1*8) - 8(1*8) = 0(0*8)

      就能确定 8 是最大公约数

     

  • 相关阅读:
    二、Python基础练习
    代码测试服同步到生产服务器
    支付宝网站支付 异步验签成功 同步验签失败
    最近机房让整改的漏洞 设置cookie httponly X-Frame-Options头未设置
    连连支付,或微信或支付宝支付,商品名称最后一个字乱码,php解决
    ci 框架新手使用
    php制作公司五章,圆形印章和椭圆形印章,正方形印章,圆角正方形印章,圆角框
    Libreoffice php使用命令行office转pdf,pdf转图片
    后台返回数据回显,使用js控制默认选中复选框和下拉框
    Nginx日志按日期切割详解(按天切割)
  • 原文地址:https://www.cnblogs.com/coderon/p/12829174.html
Copyright © 2011-2022 走看看