求兩個正整數a,b的最大公約數p和最小公倍數q。
最原始的方法是,p初始化爲min(a, b),這裏假設a < b,則p = a,
然後檢測p能否同時整除a,b,是則停止循環,
否則令p -= 1,繼續檢測
對於q,則將其初始化爲max(a,b) = b, 則q = b,
檢測q能否同時被a和b整除,是則停止循環,
否則令q += 1,繼續檢測
可以看出這樣計算效率很低,耗時大,簡單的方法是採用歐幾里德算法來求最大公約數,而利用(a * b) / p來求最小公倍數。
輾轉相除法---歐幾里德算法
以計算(1397,2413)的最大公約數爲例:
以大數2413爲被除數,以小數1397爲除數,相除得:商爲1,餘數爲1016
以大數1397爲被除數,以小數1016爲除數,相除得:商爲1,餘數爲381
以大數1016爲被除數,以小數381爲除數,相除得:商爲2,餘數爲254
以大數381爲被除數,以小數254爲除數,相除得:商爲1,餘數爲127
以大數254爲被除數,以小數127爲除數,相除得:商爲2,餘數爲0
直到能整除,則127就是最大公約數
數學證明:
b = as + r (0 <= r <= b -1),
若r=0, 顯然最大公約數爲a;
若r != 0, 由於b = as + r, 每個能整除a,r的整數都能整除b,則它能同時整除a,b
又,r = b - as, 每個能整除a,b的整數都能整除r,則能整除a,r
因此,a,b的最大公約數和a,r的最大公約數相等。
do{
r = b % a;
b = a;
a = r;
}while(!r)
遞歸的算法:
void gcd(int a, int b)
{
int m;
if (a > b)
return gcd(b, a);
if (b % a != 0)
return gcd(a, b % a);
else
return a;
}