求两数最大公约数和最小公倍数
今天下午第一节算法课留的小作业,顺手做了吧。
最大公约数和最小公倍数的概念就不解释了,暴力法也不说了不可取。
这里说下 辗转相除法和 更相减损法。
辗转相除法
辗转相除法,是求两个自然数的最大公约数的一种方法,也叫欧几里德算法。
假设m >= n,公式:gcd(m, n) = gcd(n, m mod n)
就是说m和n的最大公约数 = n和m/n的余数的,直到m mod n = 0,则n为最大公约数,而最小公倍数 = (mn)/gcd(m, n)
注:在代码中通常写做m / gcd(m,n) * n,防止mn过大爆可能会爆数据范围
上Java代码
public static int gcd(int m, int n) {
return m % n == 0 ? n : gcd(n, m % n);
}
public static void main(String[] args) {
//最大公约数 5
System.out.println(gcd(25, 15));
//最小公倍数 75
System.out.println(25 / gcd(25, 15) * 15);
}
更相减损法
公式:gcd(m, n) = gcd(n, m-n),直到m-n=0,则m或n就是最小公约数
输入两整数 m 和 n(m>=n):
1)若m-n=0,则m(或n)即为两数的最大公约数
2)若m-n≠0,则m=n,n=m-n 再回去执行第1步
public static int gcd2(int m, int n) {
return m - n == 0 ? n : gcd2(n, m - n);
}
public static void main(String[] args) {
//最大公约数 5
System.out.println(gcd2(25, 15));
//最小公倍数 75
System.out.println(25 / gcd2(25, 15) * 15);
}
连续整数检测算法
总体策略就是先从最小的开始除,如果都除尽了就return,除不尽进-1,循环。
public static int gcd3(int m, int n) {
int gcd = 1;
if (m == n) {
return n;
} else {
int min = m > n ? n : m;
for (int i = min; i > 1; i--) {
if (n % i == 0 && m % i == 0) {
return i;
}
}
return gcd;
}
}
public static void main(String[] args) {
//连续整数检测
//最大公约数 5
System.out.println(gcd3(25, 15));
//最小公倍数 75
System.out.println(25 / gcd3(25, 15) * 15);
}
分解质因数然后找所有公因数求积
m、n分别分解质因数,然后两组进行对比找出所有的公因数,求积即为gcd
public static int gcd4(int m, int n) {
if (m == n) {
return n;
} else {
//m的因数
List<Integer> _first = new ArrayList<>();
//n的因数
List<Integer> _second = new ArrayList<>();
//m分解质因数
for (int i = 2; i <= m; i++) {
while (m % i == 0 && m != 0) {
m /= i;
_first.add(i);
}
if (m == i) {
_first.add(i);
break;
}
}
//n分解质因数
for (int i = 2; i <= n; i++) {
while (n % i == 0 && n != 0) {
n /= i;
_second.add(i);
}
if (n == i) {
_second.add(i);
break;
}
}
//克隆m的所有因数
Set<Integer> tmp = new HashSet<>(_first);
//在m因数中除去m因数与n因数中共有部分 即公因数
tmp.removeAll(_second);
//克隆m所有因数
Set<Integer> exist = new HashSet<>(_first);
//除去剩余的tmp,剩余exist即为所有公因数list
exist.removeAll(tmp);
int gcd = 1;
for (Integer i :exist) {
gcd*=i;
}
return gcd;
}
}
public static void main(String[] args) {
//公因数算法检测
//最大公约数 5
System.out.println(gcd4(25, 15));
//最小公倍数 75
System.out.println(25 / gcd4(25, 15) * 15);
}