算法:最大公約數的求解方法


一 寫在開頭
1.1 本節內容
本節主要內容為幾種常見的兩個數的最大公約數(Greatest Common Divisor)的求法。

二 輾轉相除法
2.1 輾轉相除法原理
輾轉相除法也叫歐幾里得算法,是一種非常古老的求解兩個數的最大公約數的算法。其基於的原理:兩個正整數a和b(a > b),它們的最大公約數gcd等於a除以b的余數r和b之間的最大公約數。比如,10和25的最大公約數5等於25除以10的余數5和10的最大公約數;再比如51和21的最大公約數3等於51除以21的余數9和21的最大公約數,而9和21的最大公約數為3。根據上面的原理,輾轉相除法的算法流程可以如下:
步驟1:計算a與b的余數r。
步驟2:如果r為0,則返回gcd = b。否則,轉到步驟3。
步驟3:使用b的值更新a的值,使用余數r更新b的值,轉到步驟1。

2.2 輾轉相除法的C語言實現

1 long GetGCD(long a, long b)
2 {
3     return (a % b == 0) ? b : GetGCD(b, a%b);
4 }

等等,為什么不對a和b的大小進行判斷呢?上面的算法原理中不是要求a大於b嗎?如果調用時a值大於b值,比如a為51,b為21,那么情況跟上述算法原理是相符的。如果調用時a值小於b值,比如a為21,b為51,那么,21除以51的余數r為21,不為0,於是接着調用GetGCD(51, 21),看到了沒?這就和a > b的情況是一樣的了。也就是說我們根本無需判斷a和b的大小,當a值小於b值時,算法的下一次遞歸調用就能夠將a和b的值交換過來。

2.3 輾轉相除法的缺點
輾轉相除法實現時因為使用了求余運算的緣故導致其在面對大整數的時候性能不夠理想。我們應盡量避免使用求余運算。接下來介紹另一種最大公約數求解法。

三 更相減損術
3.1 更相減損術原理
更相減損術出自《九章算術》,其原理很簡單:兩個正整數a和b(a > b),它們的最大公約數等於a-b的差值c和較小數b的最大公約數。依次遞歸下去,直到兩個數相等。這相等兩個數的值就是所求最大公約數。

3.2 更相減損術的C語言實現

1 long GetGCD(long a, long b)
2 {
3     if (a == b)
4         return a;
5     else if (a > b)
6         return GetGCD(a-b, b);
7     else
8         return GetGCD(b-a, a);
9 }


3.3 更相減損術的缺點
更相減損術雖然避免了求余運算,但當兩個數a和b相差太過懸殊時,遞歸的次數會非常多,嚴重影響算法性能。比如當a為100000,b為1時,算法要遞歸99999次。

四 終極版本
一般情況下,以上兩個版本完全夠用。如果追求最佳算法性能的終極版本,那就去看《編程之美》第2.7節吧。

五 參考資料
1. 《編程之美》




免責聲明!

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



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