1. 程式人生 > >輾轉相除法與更相減損術(求最大公約數)

輾轉相除法與更相減損術(求最大公約數)

輾轉相除法:兩個正整數a和b(a>b),它們的最大公約數等於a除以b的餘數c和b之間的最大公約數。比如10和25,25除以10商2餘5,那麼10和25的最大公約數,等同於10和5的最大公約數。

以上程式碼存在取模運算,大資料較大時,其效率較差

更相減損術:兩個正整數a和b(a>b),它們的最大公約數等於a-b的差值c和較小數b的最大公約數。比如10和25,25減去10的差是15,那麼10和25的最大公約數,等同於10和15的最大公約數。

以上程式碼避免了大整數取模的效能問題,但是其依靠兩數求差的方式來遞迴,運算次數大於輾轉相除法,比如計算10000和1,就要遞迴9999次

把輾轉相除法與更相減損術的優勢結合起來,在更相減損術的基礎上使用移位運算

眾所周知,移位運算的效能非常快。對於給定的正整數a和b,不難得到如下的結論。其中gcb(a,b)的意思是a,b的最大公約數函式:

當a和b均為偶數,gcb(a,b) = 2*gcb(a/2, b/2) = 2*gcb(a>>1, b>>1)

當a為偶數,b為奇數,gcb(a,b) = gcb(a/2, b) = gcb(a>>1, b)

當a為奇數,b為偶數,gcb(a,b) = gcb(a, b/2) = gcb(a, b>>1)

當a和b均為奇數,利用更相減損術運算一次,gcb(a,b) = gcb(b, a-b), 此時a-b必然是偶數,又可以繼續進行移位運算。

比如計算10和25的最大公約數的步驟如下:

  1. 整數10通過移位,可以轉換成求5和25的最大公約數
  2. 利用更相減損法,計算出25-5=20,轉換成求5和20的最大公約數
  3. 整數20通過移位,可以轉換成求5和10的最大公約數
  4. 整數10通過移位,可以轉換成求5和5的最大公約數
  5. 利用更相減損法,因為兩數相等,所以最大公約數是5

在兩數比較小的時候,暫時看不出計算次數的優勢,當兩數越大,計算次數的節省就越明顯。

1.暴力列舉法:時間複雜度是O(min(a, b)))

2.輾轉相除法:時間複雜度不太好計算,可以近似為O(log(max(a, b))),但是取模運算效能較差。

3.更相減損術

:避免了取模運算,但是演算法效能不穩定,最壞時間複雜度為O(max(a, b)))

4.更相減損術與移位結合:不但避免了取模運算,而且演算法效能穩定,時間複雜度為O(log(max(a, b)))