1. 程式人生 > >求最大公因子(輾轉相除法原理)(擴充套件的歐幾里德演算法)

求最大公因子(輾轉相除法原理)(擴充套件的歐幾里德演算法)

    while(n != 0)
    {
        r = m % n;
        m = n;
        n = r;
    }
    printf("Their greatest common divisor is %d.\n", m);


都知道在求最大公因子(最大公約數)的時候,使用歐幾里得演算法(輾轉相除法)。下面來研究這個演算法怎麼推論出來的。

首先看:

我們用 b|a 表示b整除a。也稱b是a的因子。

用gcd(a,b)表示a和b的最大公因子。

如果 b|g 且 b|h,則對任意的整數m和n,有 b|(mg+nh)

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面推論:

假設我們有整數a,b使得d = gcd(a,b)

根據除法,我們知道

a =q1b + r1            0 <= r1 < b

所以由 d | a 和 d | b 可以推出

d | (ma+nb)   ----->   d | (a - q1b )     --------->  d | r1

現在我們知道 d | b 和 d | r1

假設有任意的整數 c 整除 b 和 r1,則有c | (mb+nr1),所以有c | (q1b+r1)  ------>  c | a

因為 c 能同時整除 a 和 b,必須有 c <= d,而d 是 a和b的最大公因子。

因此,

d = gcd(b,r1

如此迴圈,直到 ri = 0

=================================================================================================================

歐幾里德定理: gcd(a, b) = gcd(b , a mod b)


=================================================================================================================

擴充套件的歐幾里德:

道了 a 和 b 的最大公約數是 d ,那麼,我們一定能夠找到這樣的 x 和 y ,使得: 

ax + by = d = gcd(a,b)

 我們觀察到:歐幾里德演算法停止的狀態是: a= gcd , b = 0 ,

    當然這是最終狀態,但是我們是否可以從最終狀態反推到最初的狀態呢?

    假設當前我們要處理的是求出 a 和 b的最大公約數,並求出 x 和 y 使得 a*x + b*y= gcd ,而我們已經求出了下一個狀態:b 和 a%b 的最大公約數,並且求出了一組x1 和y1 使得: b*x1 + (a%b)*y1 = gcd , 那麼這兩個相鄰的狀態之間是否存在一種關係呢?

    我們知道:

a%b = a - (a/b)*b

(這裡的 “/” 指的是整除,例如 5/2=2 , 1/3=0),那麼,我們可以進一步得到:

gcd = b*x1 + (a-(a/b)*b)*y1

            = b*x1 + a*y1 – (a/b)*b*y1

            = a*y1 + b*(x1 – a/b*y1)

    對比之前我們的狀態:求一組 x 和 y 使得:a*x + b*y = gcd ,是否發現了什麼?

    這裡:

        x = y1

        y = x1 – a/b*y1


以上就是擴充套件歐幾里德演算法的全部過程,依然用遞迴寫:


應用在乘法逆元: