package methods;
/**
* Created by archur on 2016/10/14.
*/
public class DivisorGetter {
/**
* 穷举法
*/
public static int getDivisor1(int num1, int num2) {
int bigNum = num1 >= num2 ? num1 : num2;
int smallNum = num1 < num2 ? num1 : num2;
if (bigNum % smallNum == 0) {
return smallNum;
}
int divisor = 1;
for (int i = 2; i <= smallNum / 2; i++) {
if (bigNum % i == 0 && smallNum % i == 0) {
divisor = i;
}
}
return divisor;
}
/**
* 辗转相除法
* 两个正整数a和b(a>b),它们的最大公约数等于a除以b的余数c和b之间的最大公约数。
* 比如10和25,25除以10商2余5,那么10和25的最大公约数,等同于10和5的最大公约数。
*/
public static int getDivisor2(int num1, int num2) {
int result = 1;
if (num1 > num2)
result = gcd(num1, num2);
else
result = gcd(num2, num1);
return result;
}
private static int gcd(int a, int b) {
if (a % b == 0)
return b;
return gcd(b, a % b);
}
/**
* 更相减损术
* 两个正整数a和b(a>b),它们的最大公约数等于a-b的差值c和较小数b的最大公约数
*/
public static int getDivisor3(int num1, int num2) {
if (num1 == num2)
return num1;
else if (num1 > num2)
return getDivisor3(num1 - num2, num2);
else
return getDivisor3(num2 - num1, num1);
}
/**
* 更相减损术+辗转相除法
*/
public static int getDivisor4(int num1, int num2) {
if (num1 == num2)
return num1;
else {
if (num1 < num2) {
return getDivisor4(num2, num1);
} else {
if ((num1 & 1) == 0 && (num2 & 1) == 0) {
return getDivisor4(num1 >> 1, num2 >> 1) << 1;
} else if ((num1 & 1) == 0 && (num2 & 1) != 0) {
return getDivisor4(num1 >> 1, num2);
} else {
return getDivisor4(num1 - num2, num2);
}
}
}
}
/**
* 参考链接:http://blog.jobbole.com/106315/
* 1.暴力枚举法:时间复杂度是O(min(a, b)))
2.辗转相除法:时间复杂度不太好计算,可以近似为O(log(min(a, b))),但是取模运算性能较差。
3.更相减损术:避免了取模运算,但是算法性能不稳定,最坏时间复杂度为O(max(a, b)))
4.更相减损术与移位结合:不但避免了取模运算,而且算法性能稳定,时间复杂度为O(log(max(a, b)))
*/
}