两个整数a和b的公约数里最大的那一个叫做它们的最大公约数,记为[a, b];两个整数a和b的 公倍数里最小的那一个叫做它们的最小公倍数,记为(a, b)。例如: [12, 15] = 3,(12, 15) = 60。 [20, 35] = 5,(20, 35) = 140。
求两个整数的最大公约数和最小公倍数。
最大公约数和最小公倍数
问题描述
两个整数a和b的公约数里最大的那一个叫做它们的最大公约数,记为[a, b];两个整数a和b的 公倍数里最小的那一个叫做它们的最小公倍数,记为(a, b)。例如: [12, 15] = 3,(12, 15) = 60。 [20, 35] = 5,(20, 35) = 140。
求两个整数的最大公约数和最小公倍数。
设计思路
- 思路一:根据最大公约数和最小公倍数的定义
如果 a < b,则交换 a 和 b 的值,以确保 a >= b。 设置循环变量 maxGY,maxGY 从 b 开始递减至 1。在循环的过程中,如果 maxGY 同时为 a 和 b 的约数,那么最先出现的 maxGY 显然为 a 和 b 的最大公约数。 设置循环变量 minGB,minGB 从 a 开始递增。在循环的过程中,如果 minGB 同时为 a 和 b 的 倍数,那么最先出现的 minGB 显然为 a 和 b 的最小公倍数。
- 思路二:根据“辗转相除法”(“欧几里得算法”)求最大公约数,根据定理求最小公倍数
如果 a < b,则交换 a 和 b 的值,以确保 a >= b。 “辗转相除法”的算法思想是:
(1)a 除以 b 得余数 r,若 r = 0,则 b 为所求的最大公约数;
(2)若 r ≠ 0,以 b 为 a,以 r 为 b,继续步骤(1)。
例如:求(377, 319)
377 ÷ 319 = 1(余 58)
319 ÷ 58 = 5(余 29)
58 ÷ 29 = 2(余 0)
所以,(377, 319) = 29
求出最大公约数之后,可以根据如下定理求最小公倍数:(a, b) * [a, b] = a * b。
Swift 3.0 代码实现
求两个整数的最大公约数和最小公倍数(思路一:根据最大公约数和最小公倍数的定义)
func calMaxGYAndMinGB1(a : Int, b : Int) -> (maxGY : Int, minGB: Int) {
var a = a
var b = b
if a < b {
(a, b) = (b, a)
}
var maxGY = b
while maxGY > 1 {
if a % maxGY == 0 && b % maxGY == 0 {
break
}
maxGY -= 1
}
var minGB = a
while true {
if minGB % a == 0 && minGB % b == 0 {
break
}
minGB += 1
}
return (maxGY, minGB)
}
calMaxGYAndMinGB1(a: 12, b: 15)
calMaxGYAndMinGB1(a: 20, b: 35)
求两个整数的最大公约数和最小公倍数(思路二:根据“辗转相除法”(“欧几里得算法”))
func calMaxGYAndMinGB2(a : Int, b : Int) -> (maxGY : Int, minGB: Int) {
var a = a
var b = b
let ab = a * b
if a < b {
(a, b) = (b, a)
}
var r = a % b
while r != 0 {
a = b
b = r
r = a % b
}
return (b, ab / b)
}
calMaxGYAndMinGB2(a: 12, b: 15)
calMaxGYAndMinGB2(a: 20, b: 35)
算法理解
- 思路一:根据最大公约数和最小公倍数的定义。两个整数a、b,先保证前一个数比后一个数大,则,最大公约数可能是较小的那个数,如果不是,则循环递减1,再用两个数对减1后的数取余,直到余数为0,找到最小公约数。较大的那个数,可能是最小公倍数,如果不是,则循环加1,通过if限制,直到找到最小公倍数。
- 思路二:根据“辗转相除法”(“欧几里得算法”)。