1,兩個數互質:如果說兩個數的公因數只有1,則可以說這兩個數互質。
歐幾里得算法求最大公約數:
首先求最大公約數,假設我們要求a和b的最大公約數
設a mod b = c;
可以得到一下的遞推過程:
a = kb + c ;
假設a , b 的最大公約數為d,則可以得到:
a = md , b = nd;
可知m , n 互質;
c = a - kb = md - knd = (m-kn)d;
我們已經知道m,n互質,則可以知道n和m-kn互質,則c和b的最大公約數也是d;
所以由以上的推論,我們可以得到,a , b的最大公約數等於b和a mod b 的最大公約數,遞歸迭代運算,直到兩個數相等的時候,此時的a和b的值即為最大公約數。
int -2147483648 ~ +2147483647 (4 Bytes)
unsigned int 0 ~ 4294967295 (4 Bytes)
long == int
long long -9223372036854775808 ~ +9223372036854775807 (8 Bytes)
歐幾里得算法求最大公約數的局限性:
在應用輾轉相除法求最大公約數的時候,如果利用上面的方法求最大公約數,如果要對大整數求最大公約數,輾轉相除法的效率就出現了一定的問題,實際上對於大整數來說,大整數相除的時間開銷是非常昂貴的,這就是輾轉相除法的局限性。
解決方法:
可以借鑒歐幾里得的輾轉相除法,既然是取模運算導致的問題,那么我們就不用取模運算,換用“-”運算,即 f(x,y)=f(x-y,y);深入考慮一下發現在算法運行的過程可能會出現x<y的情況,這時候要交換x和y,但是結果不受影響。再來看看代碼吧。
BigInt GCD(BigInt x,BigInt y)
{
if(x < y) return GCD(y,x);
return (!y) ? x : GCD(x-y,y);
}
代碼中用到的BigInt是大整數類,可以存儲成百上千位的整數。這個類怎么實現呢?這里不多說,具體網上有好多的相關文章來講解高精度算法的,要是看書籍的話,強烈推薦ACM大牛劉汝佳的《算法競賽入門經典》一書,對高精度的介紹還是非常好的。
對於大數運算問題是解決了,然而,細心的讀者會發現,這個算法引入了另外一個問題,那就是當x和y相差很多時,算法的迭代次數會過高,導致了算法的效率較低,例如計算GCD(100000000000001,1)。這種情況確實存在啊,於是我們要考慮其他的優化了。
兩個數的最小公倍數=兩個數的乘機/最大公約數;