C++ 最大公约数与最小公倍数
C++ 最大公约数与最小公倍数
原创 已于 2023-02-28 17:11:31 修改 · 粉丝可见 · 4.9k 阅读 · 20 · 40 · 本内容遵循CC 4.0 BY-SA版权协议 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 · 编辑
文章链接:https://blog.csdn.net/hacker_51/article/details/129263100
(一)简单的两个正整数 求最大公约数(引入专题)

思路:
根据 “欧几里得算法” ,即 “辗转相除法” 原理如下:
| 题意: 求出 a , b 两个正整数的最大公约数 设 k = a / b, r = a % b 即 a = k * b + r 又设 d 为 a 和 b 的一个公约数 那么由 r = a - k * b, 可知 d 也是 r 的一个公约数 所以 d 是 b 和 r 的一个公约数 又因为 r = a % b, 所以 d 也是 b 和 a % b 的一个公约数 所以 d 是 a 和 b 的公约数,也是 b 和 a % b 的公约数 因为 d 的任意性,所以 a 和 b 的公约数 都是 b 和 a % b 的公约数 由 a = k * b + r ,同理可以证明: b 和 a % b 的公约数 都是 a 和 b 的公约数 所以 a 和 b 的公约数与 b 和 a % b 的公约数 全部相等,所以最大公约数也相等。 所以 Gcd(a,b) == Gcd(b,a % b) |
|---|
根据以上证明,得出规律:
如果 a < b 那么结果是 a 和 b 之间的数值交换 即 a % b = a,Gcd(b, a % b) == Gcd(b,a)
如果 a > b 那么 根据 Gcd(a,b) == (b, a%b) 进行规模的减小,此时需要一个递归边界
这个递归边界就是 : Gcd(a,0) 因为 0 和任意一个整数 a 的最大公约数 就是 a (注:不是 0)
所以总结如下:
1、 递归方式:Gcd(a,b) == Gcd(b,a % b)
2、递归边界: Gcd(a,0) == a
函数代码实现如下:
1 | |
化简写法:
1 | |
(一)解题源码:
1 | |
(二)求 多个数值 的最大公约数

思路:
根据 (一)简单的两个正整数 求 最大公约数 (引入专题) 的 对两个正整数的最大公约数 证明详解,我们可以得知:
设 求出 a,b,c 三个数值的 最大公约数
我们 根据 (一) 最后得出 Gcd(a,b) == d ,最后 b == 0
这时,我们可以换个角度去理解 求出了 a 和 b 最大公约数 d 后,令 b == c
此时 b != 0,继续 辗转相除 最后 b == 0,得出 最终就可以得出 a,b,c 三个数值的 最大公约数了
代码实现如下:
1 | |
(三) 求两个正整数的最小公倍数

思路:
最小公倍数的求解,是在最大公约数的基础上进行的,当得到 a 和 b 的最大公约数 d 后,
我们的最小公倍数就是 a * b / d,这个公式我们可以通过集合去理解:

通过上面的图,我们可以知道, 最大公约数 d 是 a 和 b 的交集,而 最小公倍数 就是我们 a 和 b的并集,所以要得到最小公倍数,a * b 时,会使 公因子 多计算了一遍,因此要除掉一次公因子,所以就得到了 最小公倍数: a * b / d
又由于 a * b 时,当数值比较大时,可能会使 计算结果溢出,所以更恰当的写法是:a / d * b
因为 d 为 a 和 b 的最大公约数,所以, a / d 一定可以整除。
所以最小公倍数的函数是:
1 | |
所以代码实现如下:
1 | |
(四)求多个正整数的最小公倍数

思路:
与求多个数值的最大公约数的思路大致相似,当我们求出其中的两个数值的最小公倍数后,将该最小公倍数看做独立的一个数值,相继与剩余的多个数值,进行相继的求最小公倍数数值,最后得出结果多个数值的最小公倍数。
代码实现如下:
1 | |
觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭
wechat pay
ali pay