求最大公約數及其優化演算法

2021-10-09 05:36:04 字數 2115 閱讀 8650

題目:寫一段**,求兩個數的最大公約數,盡量優化演算法的效能。

方案1:輾轉相除法

基於該定理,我們可以首先計算出a除以b的餘數c,把問題轉化成求b和c的最大公約數,然後計算出b除以c的餘數d,把問題轉化成求c和d的最大公約數;再計算出c除以d的餘數e,把問題轉換成求d和e的最大公約數…以此類推,逐漸把兩個較大整數之間的運算簡化成兩個較小整數之間的運算,直到兩個數可以整除,或者其中乙個數減小到1為止。

**實現:

/**

* 輾轉相除法求最大公約數

* @param a @param b 求a和b的最大公約數

* @return 返回最大公約數

*/public

static

intgetgreatestcommondivisor

(int a,

int b)

return

getgreatestcommondivisor

(big%small,small)

;}

缺點:輾轉相除法在兩個數較大時,進行取模運算(%)效能會比較差。

方案2:更相減損術

基於該定理:首先計算出a和b的差值c,把問題轉化為求b和c的最大公約數;然後計算出c和b的差值d,計算出…以此類推,逐漸把兩個較大整數之間的運算簡化為兩個較小整數之間的運算,直到兩個數可以相等為止,最大公約數就是最終相等的這兩個數的值。

**實現:

//更相減損術求最大公約數

public

static

intgetgreatestcommondivisor

(int a,

int b)

int big=a>b?a:b;

int small=areturn

getgreatestcommondivisor

(big-small,small)

;}

缺點:更相減損術利用兩數求差的方式進行遞迴,其運算次數遠遠大於輾轉相除法。

最終方案:

具體步驟:

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

當a為偶數,b為奇數時,getgreatestcommondivisor(a,b)=2*getgreatestcommondivisor(a/2,b)=2*getgreatestcommondivisor(a>>1,b)

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

時間複雜度:o(max(a,b))

**實現:

//最終方案:移位運算

public

static

intgetgreatestcommondivisor

(int a,

int b)if(

(a&1)==

0&&(b&1)==

0)elseif(

(a&1)==

0&&(b&1)!=

0)elseif(

(a&1)!=

0&&(b&1)==

0)else

}

時間複雜度:o(log(max(a,b)))

最大公約數簡便演算法 最大公約數演算法

1 查詢約數法 先分別找出每個數的所有約數,再從兩個數的約數中找出公有的約數,其中最大的乙個就是 最大公約數 例如,求 12 和 30 的最大公約數 12 的約數有 1 2 3 4 6 12 30 的約數有 1 2 3 5 6 10 15 30 12 和 30 的公約數有 1 2 3 6,其中 6 ...

求最大公約數

最新用了三種演算法實現了求最大公約數的演算法,用的c 寫的,最大公約數也是我們生活中常見的問題 1 窮舉法 主要 如下 if a b for i 1 i a i 演算法分析 窮舉法先將a,b兩值比較大小並且互換,再進行與各種數的整除,如果這個數能同時被a,b整除,那麼這個數就為最大公約數,這種演算法...

求最大公約數

暴力列舉法很簡單,從較小整數的一班開始,試圖找到乙個合適的整數i,檢查這個整數i是否被a和b同時整除 暴力列舉法求最大公約數 param a param b return public static int getgreatestcommondivisor v1 int a,int b for in...