輾轉相除法及其原理


輾轉相除法是一種用於計算兩個整數最大公約數的算法,核心是運用了 gcd( a, b ) = gcd( b, a  mod  b ) 這一公式(其中 b != 0 )

在詳細介紹輾轉相除法之前我想先介紹幾個概念

但如果你僅想觀看代碼,那么請點擊 代碼

如果你僅想了解 gcd( a, b ) = gcd( b, a % b ) 的證明,請點擊 證明

整除

對於整數 a 和整數 b( b ≠ 0 ),若存在整數 q,使得 a = q * b,那么稱 a 能被 b 整除

例如 14 = 2 * 7,那么 14 能被 7 整除

約數與倍數

若整數 a 能夠被整數b整除,則稱 b 是 a 的約數(因數),a 是 b 的倍數

例如 14 能夠被 7 整除,那么 7 就是 14 的約數,14 就是 7 的倍數

公約數

若整數 d 既是整數 a 的約數,也是整數 b 的約數,那么 d 是 a, b 的公約數

例如 7 即是 14 的約數,也是 21 的約數,那么 7 是 14 與 21 的公約數

最大公約數

公約數中最大的整數便稱為最大公約數,整數 a 與整數  b 的最大公約數記為 gcd( a, b ),也記為 ( a, b )

例如 14 與 21 的公約數有 { ±1,±7 },其中整數 7 是最大的公約數,那么 gcd( 14, 21 ) = 7

輾轉相除法

這里先給出幾個定理,證明過程最后再敘述

① gcd( a, b ) = gcd( b, a )

② gcd( a, b ) = gcd( |a|, |b| )

③ gcd( a, 0 ) = |a|,  其中 a ≠ 0, 即 0 和任意整數 a 的最大公約數均為 |a|

④ 設 a, b, c, q 是四個整數,若有 a = q * b + c,則 gcd( a, b ) = gcd( b, c )

通俗地說,若 c 是 a 除以 b 的余數,那么 a 和 b 的最大公約數等於 b 和 c 的最大公約數

 

有了上述那些定理,我們便有了求兩個數最大公約數的方法:

例如求 15 和 21 的最大公約數

我們知道,15 的約數有 { ±1,±3,±5,±15 },21 的約數有 { ±1,±3,±7,±21 }

那么 15 和 21 的公約數為 { ±1,±3 },最大公約數是 3,即 gcd( 15, 21 ) = 3

 

運用之前提到過的那些定理

我們發現 15 = 0 * 21 + 15, 那么 gcd( 15, 21 ) = gcd( 21, 15 )

又 21 = 1 * 15 + 6 , 那么 gcd( 21, 15 ) = gcd( 15, 6 )

又 15 = 2 * 6 + 3,那么 gcd( 15, 6 ) = gcd( 6, 3 )

又 6 = 2 * 3 + 0,那么 gcd( 6, 3 ) = gcd( 3, 0 )

又 gcd(3, 0 ) = 3,故 gcd( 15, 21 ) = 3

 

總結一下,求整數 a 和整數 b 的最大公約數的方法

取整數 a 和整數 b 的絕對值

if  b 的值為 0

       gcd( a, b ) = a

else

       gcd( a, b ) = gcd( b, a mod b )

 

代碼(c語言)

/*求a與b的最大公約數 遞歸*/
int gcd(int a,int b)
{
    //a和b同時為0時無法求出最大公約數 
    if(a==0 && b==0) return -1;
    
    if(a<0) a=-a;
    if(b<0) b=-b;
    
    if(b==0) return a;
    else return gcd(b,a%b);
}
/*求a與b的最大公約數 非遞歸*/
int gcd(int a,int b)
{
    //a和b同時為0時無法求出最大公約數 
    if(a==0 && b==0) return -1;
    
    if(a<0) a=-a;
    if(b<0) b=-b;
    
    int c;
    while(b!=0)
    {
        c=a%b;//求余數 
        a=b;
        b=c;
    }
     
    return a;
}

 

定理證明

①  gcd( a, b ) = gcd( b, a )

設整數 a 的因數為 { ±a1, ±a2, …, ±an },整數 b 的因數為 { ±b1, ±b2, …, ±bm }

最大公約數是兩約數集合交集中的最大項,與集合順序無關

故 gcd( a, b ) = gcd( b, a )

②  gcd( a, b ) = gcd( |a|, |b| )

設整數 a 的約數為 { ±a1, ±a2, …, ±an },則對任意整數 i( 1 ≤ i ≤ n ),存在整數 q,使 a = q * ai

而 -a = (-q) * ai,故 a 的約數均為 -a 的約數,同樣地, -a 的約數也為 a 的約數

故 a, -a, |a| 的約數集合相同,同理  b, -b, |b| 的約數集合也相同

而最大公約數是兩約數集合的交集中的最大項,故 gcd( a, b ) = gcd( |a|, |b| )

③  gcd( a, 0 ) = |a|,  其中 a ≠ 0

因為 a 的最大約數是 |a|

而任意非 0 整數都是 0 的約數,即 0 = 0 * n( n ≠ 0 )

故 gcd( a, 0 ) = |a|

④  設 a, b, c, q 為四個整數,若有 a = q * b + c,則 gcd( a, b ) = gcd( b, c )

(Ⅰ)設 d’ = gcd( a, b ),d” = gcd( b, c )

故有整數 q1, q2, 使得 a = q1 * d’,b = q2 * d’

將上面兩式代入 a = q * b + c 有 

c = a - q * b = q1 * d’ - q * q2 * d’ = ( q1 - q * q2 ) * d’

因為 q, q1, q2 均是整數,故 c 能被 d’ 整除,故 d’ 也是 c的約數

故 d’ 也是 b 與 c 的公約數,即有 d’ ≤ gcd( b, c ) = d”

(Ⅱ)同理有整數 q3, q4,使得 b = q3 * d”, c = q4 * d”

將上面兩式代入 a = q * b + c 有

a = q * q3 * d” + q4 * d” = ( q * q3 + q4 ) * d”

因為 q, q3, q4 均是整數,故 a 能被 d” 整除,故 d” 也是 a 的約數

故 d” 也是 a 和 b 的公約數,即有 d” ≤ gcd( a, b ) = d’

(Ⅲ)由上述知 d’ ≤ d” 且 d” ≤ d’

故 d’ = d”,即 gcd( a, b ) = gcd( b, c )

證畢


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM