如何求解最大公约数和最小公倍数?
📫关键的是 求最大公约数,最大公约数与最小公倍数有如下关系: 最小公倍数 = a * b / 最大公约数
1.辗转相除法
辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。假设两个数为 a 和 b 的具体做法是:
用 a 除以 b 得到余数 c,再用 b 除以 c 得到余数 d,再用 c 除以 d 得到 e ...... 如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的 除数 就是这两个数的最大公约数。
不用纠结 a 和 b 哪个较大
如果 a < b,那么第一次 a % b == a ,第二次又成了 a > b
解题步骤
- 通过键盘输入两个需要求解的数a,b
- 用 b 对 a 取余,如果取余结果等于较小数a,算法终止,当前a或b即为最大的公约数
- 若取余结果不等于较小数a,则转到第二步
public static int gcfI(int a, int b) {
int temp = 0;
while (b != 0) {
temp = a % b;
a = b;
b = temp;
}
return a;
}
// 辗转相除-递归
public static int gcfI_rec(int a, int b) {
if (a % b == 0) {
return b;
} else {
return gcfI_rec(b, a % b);
}
}
求解最小公倍数
public static int lcmI(int a, int b) {
// a*b/最大公约数
return a * b / gcfI(a, b);
}
2. 穷举法
穷举法的基本思想:
根据题目的部分条件确定答案的大致范围,并在此范围内对所有可能的情况逐一验证,直到全部情况验证完毕。
- 若某个情况验证符合题目的全部条件,则为本问题的一个解;
- 若全部情况验证后都不符合题目的全部条件,则本题无解。
穷举法也称为枚举法。穷举法时最通用的,也是最傻瓜式的一种算法,通过循环递增或者循环递减的方法来遍历所有合理范围内的数,通过判断是否满足条件来结束程序,从而得到最大公约数
解题步骤
- 通过键盘输入两个需要求解的数
- 比较两数的大小,找出较小的数
- 采用循环递减的方法从最小数开始递减至1
- 判断当两数的取余都等于0时跳出循环
- 当前数即为最大的公约数
public static int gcfII(int a, int b) {
//求出两数中的较小值
int ans = Math.min(a, b);
while (ans > 0) {
if (a % ans == 0 && b % ans == 0) {
break;
}
ans--;
}
return ans;
}
求解最小公倍数
// [2-穷举法] 求最小公倍数
public static int lcmII(int a, int b) {
int num1, num2, ans;
ans = num1 = a > b ? a : b; //两数较大值
num2 = a > b ? b : a; //两数较小值
while (true) {
if (num1 % num2 == 0) {
break;
}
num1 += ans;
}
return num1;
}
3.更相减损法
更相减损术是出自《九章算术》的一种求最大公约数的算法,它原本是为约分而设计的,但它适用于任何需要求最大公约数的场合。原文是:
1 |
|
如果需要对分数进行约分,那么)可以折半的话,就折半(也就是用2来约分)。如果不可以折半的话,那么就比较分母和分子的大小,用大数减去小数,互相减来减去,一直到减数与差相等为止,用这个相等的数字来约分。
解题步骤
- 通过键盘输入两个需要求解的数a,b
- 比较两数的大小,找出较小的数,默认a为较小的数
- 较大数b减去较小数a,如果相减结果等于较小数a,算法终止,当前a或b即为最大的公约数
- 若减结果不等于较小数a,则转到第二步
public static int gcfIII(int a, int b) {
while (a != b) {
if (a > b) {
a = a - b;
} else {
b = b - a;
}
}
return a;
}
// [递归求解]
public static int gcfIII_res(int a, int b) {
//保证 a > b
if (a < b) {
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
if (a - b == b) {
return b;
} else {
return gcfIII_res(a - b, b);
}
}
求解最小公倍数采用最大公约数
4.多个数的最大公约数和最小公倍数
利用传递性,利用循环两两求解相邻两数的最大公约数和最小公倍数
/**
* @Author: iqqcode
* @Date: 2020-12-03 10:31
* @Description:求任意个数字的最小公倍数(LCM)和最大公约数(GCD)
*/
public class Main3 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String str = in.nextLine();
String[] ss = str.split(" ");
int[] nums = new int[ss.length];
for (int i = 0; i < ss.length; i++) {
nums[i] = Integer.valueOf(ss[i]);
}
int gcd = nums[0], lcm = nums[0];
//两两求出多个数的最大公约数
for (int i = 0; i < nums.length; i++) {
gcd = GCD(gcd, nums[i]);
}
System.out.println(nums.length + "个数的最大公约数为: " + gcd);
for (int i = 0; i < nums.length; i++) {
lcm = LCM(lcm, nums[i]);
}
System.out.println(nums.length + "个数的最小公倍数为: " + lcm);
}
// 求两数的最小公倍数
public static int LCM(int a, int b) {
return a * b / (GCD(a, b));
}
// 求两数的最大公约数
public static int GCD(int a, int b) {
return b == 0 ? a : GCD(b, a % b);
}
}
🔗原文链接 XUST_Kevin