利用递归求最大公约数和最小公倍数

时间:2021-01-10 00:30:33

使用欧几里德算法,这个已经有2000+年的历史了,这个比起上一个来的要高效,假设我们的最大公约数表示为f(a,b),并且有a>=b>0,
欧几里德就给了我们一个很好的定理,f(a,b)=f(b,a%b),有了这个等式我们就很容易得出这个算法的递归式,现在我们来看下这个等式是怎么来的
设有 r=a/b ,q=a%b
所以就有 a=a/b*b+q ----(这里的a/b*b!=a ,原因就是我们用的是整数来计算的)
也就是a=r*b+q 变换一下有:q=a-r*b 设d=f(a,b),a/d=m,b/d=n;则 有q=dm-r*dn=d(m-rn)
所以q/d也为0;设d|q表示d是q的约数;以下相同;
又有d|b;所以有d|(b,q),设D是(b,q)的最大公约数,则会有d<=D=f(a=r*b+q,由于D|(b,q),所以D|a,所以有D|(a,b)

所以有D<=d=f(a,b),结合上部分就有d<=D <+d,及D=d;

 1 import java.util.Scanner;
2
3 public class Test_4 {
4 public static int f(int a, int b) { // 求最大公约数
5 if (a < b) {// 保证a大于b
6 int temp = a;
7 a = b;
8 b = temp;
9 }
10 if (b == 0) {
11 return a;
12 }
13 return f(b, a % b);
14 }
15
16 public static int min(int a, int b) {// 求最小公倍数
17 return a * b / f(a, b); // 直接用两个数相乘来除以最大公倍数的方法
18 }
19
20 public static void main(String[] args) {
21 Scanner sc = new Scanner(System.in);
22 int n = sc.nextInt();
23 int m = sc.nextInt();
24 int sum = f(n, m);
25 System.out.println(sum);
26 int sum2 = min(n, m);
27 System.out.println(sum2);
28 }
29 }