最大公因数问题
任给两个不全为零的整数,必存在一个的数,它同时是两个数的因子,这个数称为公因数。
不互质的两个数的公因数可以有多个,寻找最大的公因数就被称为最大公因数问题。
设有两个非零整数$a,b$,其最大公因数可表示为
$$ (a,b) $$例如,
$$ (4,6) = 2 $$短除法
小学二年级时我们已经知道,可以使用短除法来先找出所有的较小公因数,再把他们相乘。
例如求$(12,16)$,

对于较小的整数,这个方法也蛮好用的,但对于稍大的数,我们很难看出除数是几。比如$(5423,3157)$,使用短除法,找第一个除数都要花不少时间。

不难看出,短除法的思路是不断将两个数同时倍比缩小,直到无法继续同除一个数,在这个过程中也就找到了这个最大公因数的因式。但关键在于无法确定每一步的除数,实际情况可能是一个一个试,保险起见还可能是从小到大试。这样的复杂度无异于直接将两数都分解,但我们只需要最大公因数,而我们却多此一举,找出了这个数的因式。
依据这个算法,可以写成
|
|
辗转相除法
定理:设整数$a/b$的余数为$r$,则
$$(a,b)=(b,r)$$通过不断重复,直到$b_i/r_i=c$可以整除,那么$(a,b)=r_i$
以$(5423,3157)$为例,

最后$22/11=2$,最后的除数$11$就是最大公因数。
代码实现
该算法是循环过程,当$a>b$时,运算r_1=a%b ,重复r_i=b_(i-1)%r_(i-1),直到r_i=0,输出r_(i-1)。
代码实现如下,
|
|
注意到,这里不用判断$a,b$的大小,如果 $a<b$,第一次相除后变成了gcd(b,a)
对比短除法,可谓是相当简洁了。
最小公倍数问题
求一个两个数的最小公倍数$(GCD)$,可以用
$$ \begin{aligned} lcm(a,b) = \frac{|a \times b|}{gcd(a,b)} \end{aligned} $$已知最大公因数,即可求出最小公倍数
代码实现
|
|