求最大公因子(輾轉相除法原理)(擴充套件的歐幾里德演算法)
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
以上就是擴充套件歐幾里德演算法的全部過程,依然用遞迴寫:
應用在乘法逆元: