整除性与最大公因数

关注我的公众号c137Lab获取更多相关内容

在这里插入图片描述

Def: 两个数 a a a b b b (不全为零)的最大公因数是整除他们两个的最大数,记为 g c d ( a , b ) gcd(a,b) gcd(a,b). 若 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1,则称 a a a b b b 互素.

欧几里得算法

  • 下面先给出欧几里得算法的定理

定理(欧几里得算法) 要计算两个整数 a a a b b b 的最大公因数,先令 r − 1 = a r_{-1}=a r1=a r 0 = b r_0=b r0=b,然后计算相继的商和余数
r i − 1 = q i + 1 ∗ r i + r i − 1 ( i = 0 , 1 , 2 , ⋯   ) r_{i-1}=q_{i+1}*r_i+r_{i-1}\quad(i=0,1,2,\cdots) ri1=qi+1ri+ri1(i=0,1,2,)
直到某余数 r i − 1 r_{i-1} ri1 为 0. 最后的非零余数 r n r_n rn 就是 a a a b b b 的最大公因数。

  • 浅显易懂的举例:计算 g c d ( 36 , 132 ) gcd(36, 132) gcd(36,132)
  1. 将 132 除以 36 得商 3与余数 24
    132 = 3 ∗ 36 + 24 132=3*36+24 132=336+24
  2. 取 36 ,用前一步的余数 24 除 36 得
    36 = 1 ∗ 24 + 12 36=1*24+12 36=124+12
  3. 用 12 除 24 求得余数 0
    24 = 2 ∗ 12 + 0 24=2*12+0 24=212+0
    ​ 欧几里得算法说明当得到余数 0 时,前一步的余数就是最初两个数的最大公因数。故求得 g c d ( 132 , 36 ) = 12 gcd(132, 36)=12 gcd(132,36)=12

  • 下面我们分析欧几里得算法,假设求 g c d ( a , b ) gcd(a, b) gcd(a,b) ,对于一般情景,有:

a = q 1 ∗ b + r 1 (1) a=q_1*b+r_1 \tag{1} a=q1b+r1(1)
b = q 2 ∗ r 1 + r 2 (2) b=q_2*r_1+r_2 \tag{2} b=q2r1+r2(2)
r 1 = q 3 ∗ r 2 + r 3 (3) r_1=q_3*r_2+r_3 \tag{3} r1=q3r2+r3(3)

r 2 = q 4 ∗ r 3 + r 4 (4) r_2=q_4*r_3+r_4 \tag{4} r2=q4r3+r4(4)

⋮ \vdots

r n − 3 = q n − 1 ∗ r n − 2 + r n − 1 (5) r_{n-3}=q_{n-1}*r_{n-2}+r_{n-1} \tag{5} rn3=qn1rn2+rn1(5)

r n − 2 = q n ∗ r n − 1 + r n (6) r_{n-2}=q_n*r_{n-1}+r_n \tag{6} rn2=qnrn1+rn(6)

r n − 1 = q n + 1 ∗ r n + 0 (7) r_{n-1}=q_{n+1}*r_n+0 \tag{7} rn1=qn+1rn+0(7)

如果令 r 0 = b r_0=b r0=b r − 1 = a r_{-1}=a r1=a 则每行可以写成:
r i − 1 = q i + 1 ∗ r i + r i + 1 r_{i-1}=q_{i+1}*r_i+r_{i+1} ri1=qi+1ri+ri+1
​ 那么,为什么说 r n r_n rn 就是 a a a b b b 的最大公因数呢?我们先来证明 r n r_n rn a a a b b b 的公因数:

**证:**式 ( 7 ) (7) (7) 表明 r n r_n rn 整除 r n − 1 r_{n-1} rn1 ,再观察式 ( 6 ) (6) (6) ,因为 r n r_n rn 整除 r n − 1 r_{n-1} rn1 r n r_n rn,可以发现 r n r_n rn 整除 r n − 2 r_{n-2} rn2

向上递推直到 i = 0 i=0 i=0 ,此时可以得到 r n r_n rn 整除 r − 1 r_{-1} r1 r 0 r_0 r0 ,即 r n r_n rn 整除 a a a b b b ,故 r n r_n rn a a a b b b 的公因数.

接下来证明 r n r_n rn a a a b b b 的最大公因数:

**证:**假设 d d d a a a b b b 的任意公因数。从式 ( 1 ) (1) (1) 可得, d d d 整除 a , b , r 1 a,b,r_1 a,b,r1 ,再观察式 ( 2 ) (2) (2) 可得 d d d 整除 b , r 1 , r 2 b,r_1,r_2 b,r1,r2 ,向下递推直到式 ( 7 ) (7) (7) ,可得 d d d 整除 r n r_n rn

由于 d d d a a a b b b 的任意公因数且 d d d 整除 r n r_n rn ,可得 r n r_n rn a a a b b b 的最大公因数

​ 既然已经得到了欧几里得算法的确可以求得最大公因数。那么,这一算法的效率如何呢,要经过多少次计算才能得到为 0 的余数呢?

​ 或者说,这一算法有没有可能因为无法得到为 0 的余数而永无止境?

以下证明过程,证明了欧几里得算法至多在 2 l o g 2 ( b ) 2log_2(b) 2log2(b) 步终止:

**证:**已知以下两式:
r i − 2 = q i ∗ r i − 1 + r i (8) r_{i-2}=q_i*r_{i-1}+r_i\tag{8} ri2=qiri1+ri(8)

r i − 1 = q i + 1 ∗ r i + r i + 1 i = 0 , 1 , 2 , ⋯ (9) r_{i-1}=q_{i+1}*r_i+r_{i+1}\quad i=0,1,2,\cdots\tag{9} ri1=qi+1ri+ri+1i=0,1,2,(9)

( 8 ) (8) (8)减去式 ( 9 ) (9) (9)整理得
r i − 2 = ( q i + 1 ) ∗ r i − 1 + ( 1 − q i + 1 ) ∗ r i − r i + 1 (10) r_{i-2}=(q_i+1)*r_{i-1}+(1-q_{i+1})*r_i-r_{i+1}\tag{10} ri2=qi+1ri1+(1qi+1)riri+1(10)
将式 ( 9 ) (9) (9)代入式 ( 10 ) (10) (10)整理得:
( q i ∗ q i + 1 + 1 ) ∗ r i + q i ∗ r i + 1 = r i − 2 (q_i*q_{i+1}+1)*r_i+q_i*r_{i+1}=r_{i-2} (qiqi+1+1)ri+qiri+1=ri2
由于 q q q 是正整数,可得:
r i − 2 > 2 r i r_{i-2}>2r_i ri2>2ri
通过递推可以得到:
2 − i 2 ∗ b > r i 2^{-\frac{i}{2}}*b>r_i 22ib>ri
2 − i 2 ∗ b = 1 2^{-\frac{i}{2}}*b=1 22ib=1 时算法结束,此时步数 i = 2 l o g 2 ( b ) i=2log_2(b) i=2log2(b)


What‘s more:

由于欧几里得算法的最大步数是 2 l o g 2 ( b ) 2log_2(b) 2log2(b),十进制数 b b b 可以表示为 b = m ∗ 1 0 n b=m*10^n b=m10n 将其代入,可以得出:欧几里得算法的最大步数约等于 b b b 的位数的 7 倍。因此,即使是在对非常大的数求公因式时,依然可以保持很高的效率。

欧几里得算法的代码实现

a = int(input())
b = int(input())
if a == 0 or b == 0:
    print("illegal input")
else:
    while b != 0:
        a, b = b, a % b
    print("gcd(a,b)=", a)

参考文献:A Brief Introduction to Number Theory --Joseph H.Silverman

猜你喜欢

转载自blog.csdn.net/verse_monger/article/details/105440752
今日推荐