最大公约数
1、欧几里德算法 GCD(A,B) = GCD(B, A%B);
证明:a可以表示成a = kb + r,则r = a mod b
假设d是a,b的一个公约数,则有
d|a, d|b,而r = a - kb,因此d|r
因此d是(b,a mod b)的公约数
假设d 是(b,a mod b)的公约数,则
d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证
递归实现代码:
/**
* 递归实现最小公约数
* ---- 欧几里德算法
* @param a
* @param b
* @return
*/
public static int GCDOuJiLiDe(int a, int b) {
if (b == 0) return a;
return GCDOuJiLiDe(b, a % b);
}
非递归实现代码:
/**
* 非递归实现最小公约数
* ---- 欧几里德算法
* @param a
* @param b
* @return
*/
public static int GCDUsingWhile(int a, int b) {
while (b != 0) {
int r = b;
b = a % b;
a = r;
}
return a;
}
2、Stein算法:
如果A=0,B是最大公约数,算法结束
如果B=0,A是最大公约数,算法结束
设置A1 = A、B1=B和C1 = 1
如果An和Bn都是偶数,则An+1 =An /2,Bn+1 =Bn /2,Cn+1 =Cn *2(注意,乘2只要把整数左移一位即可,除2只要把整数右移一位即可)
如果An是偶数,Bn不是偶数,则An+1 =An /2,Bn+1 =Bn ,Cn+1 =Cn (很显然啦,2不是奇数的约数)
如果Bn是偶数,An不是偶数,则Bn+1 =Bn /2,An+1 =An ,Cn+1 =Cn (很显然啦,2不是奇数的约数)
如果An和Bn都不是偶数,则An+1 =|An -Bn|,Bn+1 =min(An,Bn),Cn+1 =Cn
n++,转4
代码实现:
/**
* 实现最小公约数
* Stein算法
* @param a
* @param b
* @return
*/
public static int GCDUsingStein(int a, int b) {
if (a == 0) return b;
if (b == 0) return a;
if (a % 2 == 0 && b % 2 == 0) return GCDUsingStein(a >> 1, b >> 1) << 1;
else if (a % 2 == 0 && b % 2 != 0) return GCDUsingStein(a >> 1, b);
else if (a % 2 != 0 && b % 2 == 0) return GCDUsingStein(a, b >> 1);
else return GCDUsingStein(Math.abs(a - b), Math.min(a, b));
}
最小公倍数 = 2数乘积 / 2数最大公约数