概念:
最大公约数:两个整数共有因子中最大的一个
方法一:
如果两个数相等,则最大公约数为它本身,两个数不等,则用两个数依次除 两个数中最小的一个到 1,直到找到同时能被两个数除尽的那个数
代码清单:
public static int gcd1(int x, int y) { int result = 0; // 最大公约数 int min = x > y ? y : x; // 两个整数中最小的数 if (x == y) { result = x; } else { for (int i = min; i >= 1; i--) { if (x % i == 0 && y % i == 0) { result = i; break; } } } return result; }
方法二:辗转相除法
假设用f(x,y) 表示x , y 的最大公约数,取 k = x/y , b = x%y ,则 x = ky + b ,如果一个数能够同时整除 x 和 y ,则 x 和 y 的公约数与 b 和 y 的公约数是相同的,其最大公约数也是相同的,则有 f(x,y) = f(y , x%y) (x>=y>0)。如此便可把原问题转化为求两个更小数的最大公约数,知道其中的一个数为0,剩下的另外一个数就是两者的最大公约数。
示例如下:
F(42,30) = F(30,12) = F(12,6) = F(6, 0) = 6
代码清单:
public static int gcd2(int x, int y) { return (y == 0) ? x : gcd(y, x % y); }
方法三:
方法二中用到了取模运算。但对于大整数而言,取模运算(用到除法)是非常昂贵的开销。能不能不用取模式运算呢?
采用类似辗转相除法的分析,如果一个数能同时整除x和y ,则必能同时整除x-y和y
即x 和 y 的公约数和 x - y 和 y的公约数是相同的,其最大公约数也是相同的。即
F(x , y) = F (x-y , y)
示例如下:
F(42,30) = F(30,12) = F(12,18) = F(18, 12)= F( 12 ,6 ) = F( 6, 6) = F( 6, 0) = 6
代码清单:
public int gcd3(int x, int y) { if (x < y) { return gcd3(y, x); } if (y == 0) { return x; } else { return gcd3(y, x-y); } }