//题目:求两个数的最大公约数
//解法1:使用辗转相除法:f(a,b) = f(a%b,b),直到一个数为0,会有两个比较大的数做除法,对程序造成较大开销
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(getGcd1(42,80));
System.out.println(getGcd2(42,30));
}
//递归的写法
public static int getGcd1(int a ,int b){
if(b>a){ //如果第二个大于第一个数,则换一下位置
return getGcd1(b,a);
}
if(b == 0){
return a;
}
return getGcd1(b,a%b);
}
//非递归的写法
public static int getGcd2(int a, int b){
if(b>a){
int temp = b;
b = a;
a = temp;
}
while(b!=0){ //因为第二数一直比较小,所以一定是第二数先为0
int temp = b;
b = a%b;
a = temp;
}
return a;
}
}
//解法2:因为取模运算中使用的除法运算对程序造成了很大的开销,所以可以使用辗转相减法:f(a,b) = f(a-b,b),直到一个数为0
//但缺点是需要执行的循环次数太多,如:f(10000,1)
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(getGcd1(42,80));
System.out.println(getGcd2(42,80));
}
//递归的写法
public static int getGcd1(int a ,int b){
if(b>a){
return getGcd1(b,a);
}
if(b == 0){
return a;
}
return getGcd1(a-b,b);
}
//非递归的写法
public static int getGcd2(int a, int b){
if(b>a){
int temp = b;
b = a;
a = temp;
}
while(b!=0){
a = a-b;
if(b>a){ //如果第二个数比第一个数大就换一下位置
int temp = b;
b = a;
a = temp;
}
}
return a;
}
}
//解法3:结合上面两种方法,考虑两个数字的四种情况进行处理
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(getGcd1(42,80));
System.out.println(getGcd2(42,80));
}
public static boolean isEven(int num){
if(num%2 == 0){
return true;
}else{
return false;
}
}
//递归的写法
public static int getGcd1(int a ,int b){
if(b>a){
return getGcd1(b,a);
}
if(b == 0){
return a;
}
if(isEven(a) && isEven(b)){ //如果都为偶数,f(x,y) = 2*f(x/2,y/2)
return 2*getGcd1(a>>1,b>>1);
}else if(isEven(a) && !isEven(b)){ //如果x为偶数,f(x,y) = f(x/2,y)
return getGcd1(a>>1,b);
}else if(!isEven(a) && isEven(b)){ //如果y为偶数,f(x,y) = f(x,y/2)
return getGcd1(a,b>>1);
}else{ //如果x,y都为奇数,辗转相减,f(x,y) = f(x-y,y)
return getGcd1(a-b,b);
}
}
//非递归的写法
public static int getGcd2(int a, int b){
if(b>a){
int temp = b;
b = a;
a = temp;
}
int midResult = 1;
while(b!=0){
if(isEven(a) && isEven(b)){
a = a/2;
b = b/2;
midResult = midResult*2; //需要提出一个2
}else if(isEven(a) && !isEven(b)){
a = a/2;
}else if(!isEven(a) && isEven(b)){
b = b/2;
}else{
a = a-b;
}
if(b>a){
int temp = b;
b = a;
a = temp;
}
}
return a*midResult;
}
}