1. 程式人生 > 程式設計 >漫畫演演算法筆記之求兩個數最大公約數

漫畫演演算法筆記之求兩個數最大公約數

題目

求兩個整數的最大公約數

輾轉相除法

定義

輾轉相除法,又名歐幾裡得演演算法(Euclideanalgorithm),該演演算法的目的是求出兩個正整數的最大公約數。它是已知最古老的演演算法,其產生時間可追溯至公元前300年前。這條演演算法基於一個定理:兩個正整數a和b(a>b),它們的最大公約數等於a除以b的餘數c和b之間的最大公約數。

實現

缺點

不過有一個問題,當兩個整數較大時,做a%b取模運算的效能會比較差。

更相減損術

定義

更相減損術,出自中國古代的《九章算術》,也是一種求最大公約數的演演算法。古希臘人很聰明,可是我們炎黃子孫也不差。它的原理更加簡單:兩個正整數a和b(a>b),它們的最大公約數等於ab的差值c和較小數b的最大公約數。例如10和25,25減10的差是15,那麼10和25的最大公約數,等同於10和15的最大公約數。

實現

缺點

但是,更相減損術依靠兩數求差的方式來遞迴,運算次數肯定遠大於輾轉相除法的取模方式。同時,更相減損術是不穩定的演演算法,當兩數相差懸殊時,如計算 10000 和 1 的最大公約數,就要遞迴 9999 次。

結合更相減損術和輾轉相除法

定義

眾所周知,移位運算的效能非常好。對於給出的正整數a和b,不難得到如下的結論。(從下文開始,獲得最大公約數的方法getGreatestCommonDivisor被簡寫為gcd。)

  • 當a和b均為偶數時,gcd(a,b)=2×gcd(a/2,b/2)=2×gcd(a>>1,b>>1)
  • 當a為偶數,b為奇數時,gcd(a,b)=gcd(a/2,b)=gcd(a>>1,b)
  • 當a為奇數,b為偶數時,gcd(a,b)=gcd(a,b/2)=gcd(a,b>>1)
  • 當a和b均為奇數時,先利用更相減損術運算一次,gcd(a,b)=gcd(b,a-b),此時ab必然是偶數,然後又可以繼續進行移位運算

實現

程式碼參考

gist.github.com/furuiyang07…