輾轉相除法
倆個正整數的最大公約數等于他們的余數和較小數之間的最大公約數
package gcl;
public class Gcl_1 {
/**
* 求最大公約數 轉轉相除法
*
* 缺點 取余操作效率低
*/
public static int gcl(int a,int b){
int max = a>b?a:b;
int min = a<=b?a:b;
if(max%min==0){
return b;
}
return gcl(max,max%min);
}
public static void main(String[] args) {
// System.out.println(gcl(10,5));
System.out.println(gcl(10000000,5));
}
}
結果
5
更相減損法
倆個正整數的最大公約數等于他們的差值和較小數之間的最大公約數
package gcl;
public class Gcl_2 {
/**
* 更相減損法
*
* 缺點 ,如果倆數差距太大運算次數過多
*/
public static int gcl2(int a,int b){
int max =a>b?a:b;
int min = a<=b?a:b;
if(max==min){
return min;
}
return gcl2(max-min,min);
}
public static void main(String[] args) {
System.out.println(gcl2(10,5));
}
}
結果
5
位移法
當倆個數字中任意一個數字是偶數時要通時進行右移,也就是除2操作,如果同時右移,這就要保留乘2,因為這是倆個數字的公約數。
package gcl;
public class Gcl_3 {
/**
* 通過位運算進行除2操作,當倆個數字都不偶數時進行更相減損法
*
* 判斷一個數是否是偶數, 3 &1 0010 &0001 =0 即和1 做與操作等于0及是偶數
*/
public static int gcl3(int a, int b){
int max = a>b?a:b;
int min = a<=b?a:b;
if(a==b){
return b;
}else if((a&1)==0 && (b&1)==0){
return gcl3(a>>1,b>>1)*2;
}else if((a&1)!=0 && (b&1)==0){
return gcl3(a,b>>1);
}else if((a&1)==0 && (b&1)!=0){
return gcl3(a>>1,b);
}else{
return gcl3(a,a-b);
}
}
public static void main(String[] args) {
System.out.println(gcl3(5,10));
}
}
三種方法對比,輾轉取模太慢,更相倆個數差距過大需要運算次數太多,而位運算則結合了倆種的優點,