求最大公约数的最常用的算法是欧几里得算法,也称为辗转相除法。
问题定义为求i和j的最大公约数gcd(i,j),其中i和j是整数,不妨设i>j。
算法可以递归的表示:
1.如果j能整除i,那么gcd(i,j)=j; 2.j不能整除i,令r=i%j,那么gcd(i,j)=gcd(j,r).
上面的算法对于i<j的情况也是可以的,实际上是做了一次交换。
使用C语言实现:
int gcd(int i, int j) { int r = i % j; return r == 0 ? j : gcd(j, r); }
算法正确性分析:
下面一步一步的切入
在证明之前先看一个说明: 对于两个数i=md,j=nd. i、j的最大公约数是d的充要条件是:m和n互质。 再看另一个说明: 如果m和n互质,那么(m-kn)和n也互质。 这个可以用反正法: 假设(m-kn)和n不互质,那么存在一个因子e,使得(m-kn)=en。 那么m=(k+e)n,这与m、n互质的题目条件违背,所以假设不成立。 则(m-kn)和n也互质。 算法的步骤1,显然是成立的,因为这就是最大公约数的定义。 算法的步骤2: 其实算法证明的目标是r=i%j != 0时,gcd(i,j)=gcd(j,r)。 根据已知条件,设d是i、j的最大公约数,则 i=md,j=nd,其中m、n是互质的。(如果m、n不互质,d就不是最大公约数) |
算法的步骤1,显然成立(最大公约数定义).关键是要证明步骤2. 设d是i和j的最大公约数, 那么i=md,j=nd,m和n互质(否则d不是最大公约数). 由r=i%j可以得到i=kj+r,k=⌊m/n⌋,k≥1(我们前面假设过i>j). 把i=md,j=nd代入得到 md=knd+r 那么 r=(m-kn)d m-kn和m也是互质的. 所以得到d是j和r的最大公约数.
时间: 2024-11-05 21:49:22