算法一
任何>1的整數都可以寫成一個或多個素數因子乘積的形式,且素數乘積因子以非遞減序出現。
則整數x,y可以分別標記為:
x=p1x1p2x2...pmxm
y=p1y1p2y2...pmym
(其中p1,p2,....是素數,若有必要素數因子的指數xj或yj可以為0)
(1)最大公約數 gcd(x,y)=p1min(x1,y1)p2min(x2,y2)...pmmin(xm,ym)
(2)最小公倍數 lcm(x,y)=p1max(x1,y1)p2max(x2,y2)...pmmax(xm,ym)
(3)因此,亦可得:lcm(x,y)*gcd(x,y)=x*y
按如上思路計算gcd(x,y)至少需要如下兩步
step1: decompose_to_primes(int n);//把整數n分解成素數相乘的形式
step2:get_gcd(int x,int y);//根據step1的結果按照公式(1)計算gcd(x,y)
分明顯計算量比較大。
實際上從編程的角度來看,在x,y的數值不是很大的情況下。若是單純的計算最大公約數和最小公倍數可以不必這么復雜,可以從大到小遍歷min(x,y)的約數,找到的第一個公約數即為所求。
1 int get_gcd(int x,int y) 2 { 3 int temp; 4 int i; 5 if(x>y) 6 { 7 temp=x; 8 x=y; 9 y=temp; 10 } 11 if(y%x==0) 12 return x; 13 for(i=x/2;i>1;i--) 14 if(x%i==0) 15 if(y%i==0) 16 return i; 17 return 1; 18 } 19 20 int get_lcm(int x,int y) 21 { 22 return (x*y)/(get_gcd(x,y)); 23 }
算法二
用Euclid算法(即輾轉相除法)
step1、令r為a/b所得余數(0≤r<b)。若 r= 0,算法結束,則b 即為所求,否則執行step2。
step2、a←b,b←r,重新執行step1。
1 int gcd(int x,int y)//Euclid method 2 { 3 int r; 4 if(x<y) 5 { 6 r=x; 7 x=y; 8 y=r; 9 } 10 r=x%y; 11 while(r) 12 { 13 x=y; 14 y=r; 15 r=x%y; 16 } 17 return y; 18 }
