源自:百度百科
輾轉相除法
輾轉相除法:輾轉相除法是求兩個自然數的最大公約數的一種方法,也叫歐幾里德算法。
例如,求(319,377): ∵ 319÷377=0(余319) ∴(319,377)=(377,319); ∵ 377÷319=1(余58) ∴(377,319)=(319,58); ∵ 319÷58=5(余29) ∴ (319,58)=(58,29); ∵ 58÷29=2(余0) ∴ (58,29)= 29; ∴ (319,377)=29。
用輾轉相除法求幾個數的最大公約數,可以先求出其中任意兩個數的最大公約數,再求這個最大公約數與第三個數的最大公約數,依次求下去,直到最后一個數為止。最后所得的那個最大公約數,就是所有這些數的最大公約數。
更相減損法
第一步:任意給定兩個正整數;判斷它們是否都是偶數。若是,則用2約簡;若不是則執行第二步。
第二步:以較大的數減較小的數,接着把所得的差與較小的數比較,並以大數減小數。繼續這個操作,直到所得的減數和差相等為止。
則第一步中約掉的若干個2與第二步中等數的乘積就是所求的最大公約數。
其中所說的“等數”,就是最大公約數。求“等數”的辦法是“更相減損”法。所以更相減損法也叫等值算法。
例1.用更相減損術求98與63的最大公約數。 解:由於63不是偶數,把98和63以大數減小數,並輾轉相減: 98-63=35 63-35=28 35-28=7 28-7=21 21-7=14 14-7=7 所以,98和63的最大公約數等於7。 這個過程可以簡單的寫為: (98,63)=(35,63)=(35,28)=(7,28)=(7,21)=(7,14)=(7,7)=7. 例2.用更相減損術求260和104的最大公約數。 解:由於260和104均為偶數,首先用2約簡得到130和52,再用2約簡得到65和26。 此時65是奇數而26不是奇數,故把65和26輾轉相減: 65-26=39 39-26=13 26-13=13 所以,260與104的最大公約數等於13乘以第一步中約掉的兩個2,即13*2*2=52。 這個過程可以簡單地寫為: (260,104)(/2/2) =>(65,26)=(39,26)=(13,26)=(13,13)=13. (*2*2) => 52 [1]
比較:
比較輾轉相除法與更相減損術的區別
(1)都是求最大公因數的方法,計算上輾轉相除法以除法為主,更相減損術以減法為主,計算次數上輾轉相除法計算次數相對較少,特別當兩個數字大小區別較大時計算次數的區別較明顯。
(2)從結果體現形式來看,輾轉相除法體現結果是以相除余數為0則得到,而更相減損術則以減數與差相等而得到
代碼實現
一:最簡單方法
#include <stdio.h> #include <stdlib.h> int main() { int m, n,temp,i; scanf("%d", &m); scanf("%d", &n); if (m>n) { temp = m; m = n; n = temp; } for (i = m; i >= 1;i--) if (m%i==0 && n%i==0) break; printf("%d\n", i); system("pause"); return 0; }
二:輾轉相除法(遞歸)
#include <stdio.h> #include <stdlib.h> int gcd(int a, int b) { int mod; if ((mod = a % b) == 0) return b; return gcd(b, mod); } int main() { int m, n,ret; scanf("%d", &m); scanf("%d", &n); ret = gcd(m, n); printf("%d", ret); system("pause"); return 0; }
三:輾轉相除法(非遞歸)
int gcd(int a, int b) { int mod=a % b; while (mod!=0) { a = b; b = mod; mod = a % b; } return b; }
四:更相減損法(非遞歸)
#include <stdio.h> #include <stdlib.h> #include <math.h> int gcd(int a, int b) { int val= a - b; while (val != b) { if (b>val) { a = b; b = val; } else { a = val; } val = a - b; } return val; } int main() { int m, n,ret,temp,count=0; scanf("%d", &m); scanf("%d", &n); if (m == n) { printf("%d", m); return 0; } if (m < n) { temp = m; m = n; n = temp; } while (m%2 == 0 && n%2 == 0) { count++; m /= 2; n /= 2; } ret = gcd(m, n); printf("%d", ret*((int)pow(2,count))); //使用pow需要進行(int)轉換,不然會報錯 system("pause"); return 0; }