[初等数论]欧几里得算法:最大公因数求解算法的数学证明与程序实现
对广大数学或计算机爱好者来说,找两个数的公因数向来是绕不过去的问题.本文将带大家用小学二年级的知识推出上述问题的最优算法:欧几里得算法,并展示其程序实现.以下是本文索引:
- 欧几里得算法
- 简洁的定义
- 快速的算法
- 严谨的证明
- 优雅的程序
- 斐蜀定理与更多推论
- 斐蜀定理
- 更多推论
欧几里得算法
欧几里得算法又叫辗转相除法,因最早被记载于欧几里得的《几何原本》中而得名.在我国,相同的算法则最早出现于东汉的《九章算术》中.该算法是目前已知最快的最大公因数求解算法.接下来,让我们开始深入了解该算法吧!
简洁的定义
本节内容的定义范围均为自然数系,或者用集合论的写法:
明确定义范围后,让我们先来定义除法:
显而易见,除法对自然数系并不封闭.也就是说,我们将任意两个自然数相除,结果却不一定是自然数.对于相除结果仍是自然数的,比如
设
而对于不能整除的情况,我们可以将结果表示为两个自然数,这就是我们小学学的带余除法,例如
设
上式也写作:
其中
接下来我们来定义下因数、公因数和最大公因数:
设
若
若
好了,定义到此结束,接下来让我们看看以上几个概念的基本性质吧:
以上几个性质留给读者自证.
最好的算法
准备工作完成后,让我们思考下如何计算
我们不妨假设
而当
当
当
容易发现
进一步观察
先假设以上归纳结论是正确的,容易发现我们已经得到了将两个较大数的最大公因数求解问题转化为两个较小数的求解问题,而这样的操作是可以链式执行的,比如:
将上述方法归纳一下就是欧几里得算法:
要求
由于每次带余除法后其余数必然减少,因此有限次操作后必然存在
严谨的证明
要证欧几里得算法,先要证以下命题:
证明:
由以上命题可得算法中的
优雅的程序
让我们直接上伪代码吧:
input a, b if a > b: exchange a, b while r != 0: r = b mod a b = a a = r output b
接下来,让我们看一个 C 语言实现吧!
#include <stdint.h> #include <stdio.h> uint64_t gcd(uint64_t a, uint64_t b) { if (a > b) { a = a ^ b; b = a ^ b; a = a ^ b; } loop:; uint64_t r = b % a; b = a; a = r; if (r != 0) goto loop; return b; }
斐蜀定理与更多推论
本节内容仅作为补充,因此除斐蜀定理外其余推论证明留作练习.
另外,本节内容默认定义范围为整数系
斐蜀定理
逆向观察欧几里得算法,我们可以看出:
以此类推式中的每一个
反过来,可以得到:
也就是说,可以用
其中
更多推论
以下内容请自证.
本文作者:Expector
本文链接:https://www.cnblogs.com/expector/p/euclid_algorithm.html
版权声明:本作品采用 CC BY-NC-ND 许可协议进行许可。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步