• 使用辗转相除法求两个数的最大公因数(python实现)


    数学背景:


      整除的定义:

        任给两个整数a,b,其中b≠0,如果存在一个整数q使得等式

                                           a = bq

        成立,我们就说是b整除a,记做b|a.

      性质1:如果c|a,c|b,且对于任意的整数m,n,则有c|ma + nb

      证明: 利用上述定义进行证明

                因为c|a ,c|b,所以有a = c*q1,b = c*q2,

                对于任意m,n有,ma+nb = m(c*q1) + n(c*q2) = c(m*q1 + n*q2),

                因为m*q1 +n*q2为整数,很显然有 c|ma + nb .

      带余除法: 设a,b 是两个整数,其中b > 0 ,则存在两个唯一的整数q和r,使得

                                  a = b*q + r,          0≤ r < b

                       成立.

      公因数和最大公因数的定义:

        设a1,a2,a3,......,an是n个不全为0的整数,若整数d是它们之中每一个数的因数,那么d就叫做a1,a2,a3,......,an的一个公因数.这时它们的公因数只有有限个,整数a1,a2,a3,......,an的公因数中最大的一个叫做最大公因数,记做(a1,a2,a3,......,an),若(a1,a2,a3,......,an)=1,我们说a1,a2,a3,......,an互素.

      定理1:设a,b,c是任意三个不全为零的整数,且 a = bq + c,其中q是整数,则(a,b) = (b,c).也就是说,a和b的最大公因数等于b和c的最大公因数.

      证明: 因为(a,b)是a和b的最大公因数,所以(a,b)|a,且(a,b)|b,由于c = a - bq,所以由性质1可以知道(a,b)|c,所以可以看到,(a,b)是b,c的一个公因数,而由公因数的定义可以知道 (b,c)是b,c的最大公因数,任何公因数都是小于最大公因数的,所以(a,b) ≤ (b,c).

        同样的道理可以证明 (b,c) ≤(a,b).

                因此有(a,b) = (b,c)

      辗转相除法:给任意整数 a > 0,b >0, 由带余除法,有以下等式

                        a = b*q1 + r1,     0 < r1 < b,

                        b = r1*q2 + r2,    0 < r2 < r1,

                        r1 = r2*q3 + r3,   0 < r3 < r2,

                        ......

                        rn-2  =  rn-1*q+ rn , 0< r<rn-1

                        rn-1  = r*qn+1  + rn+1  ,rn+1 = 0

                       因为 b> r1 > r2 > r3 >....,故经过有限次带余除法以后,总可以得到一个余数为0,上面rn+1 = 0

                      由上面的定理1可以知道,(a,b) = (b,r1) = (r2,r1) = ....= (rn-2,rn-1) = (rn-1,rn) = (rn,0) = rn

                      所以要想求a,b得最大公因数,就需要不断的使用带余除法,直到余数为0,就可以得到a,b的最大公因数.

    举例:


        使用辗转相除法求 288 和 158 的最大公因数

        288  = 158 * 1 + 130

        158  = 130 * 1 + 28

        130 =  28 * 4 + 18

        28 =18 * 1 + 10

        18 = 10 * 1 + 8

        10 = 8 * 1 + 2

        8 = 2 * 4

        所以(288,158) = (158,130) = (130,28) = (28,18)=(18,10)=(10,8)=(8,2)=(2,0)=2

    python 实现:


    递归

    def gcd(a,b):
        if b == 0 : return a
        return gcd(b,a % b)

     迭代

    def gcd(a,b):
        while b != 0:
            a,b = b,a%b
        return a
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法提高 P0404
    Java实现 蓝桥杯VIP 算法训练 排列问题
    Java实现 蓝桥杯VIP 算法训练 排列问题
    Java实现 蓝桥杯VIP 算法训练 排列问题
    Java实现 蓝桥杯VIP 算法训练 排列问题
    关于模态/非模态对话框不响应菜单的UPDATE_COMMAND_UI消息(对对WM_INITMENUPOPUP消息的处理)
  • 原文地址:https://www.cnblogs.com/jiaxin359/p/6080347.html
Copyright © 2020-2023  润新知