6.2. 辗转相除法
作者:互联网
1. 辗转相除法, 又名欧几里德算法(Euclidean algorithm),是求最大公约数的一种方法。它的具体做法是:用较大数除以较小数,再用出现的余数(第一余数)去除除数,再用出现的余数(第二余数)去除第一余数,如此反复,直到最后余数是0为止。如果是求两个数的最大公约数,那么最后的除数就是这两个数的最大公约数。
步骤:
两个数的最大公约数是指能同时整除它们的最大正整数。
设两数为a、b(a≥b),求a和b最大公约数的步骤如下
(1)用a除以b(a≥b),a / b = q...r1;
(2)若r1 == 0,则gcd(a,b) = q;
(3)若r1 != 0,则b / r1 = q..r2;
(4)若r2 == 0,则gcd(a,b) = r1;
(5)若r2 != 0, 则重复上述(3),(4)步骤;
实际过程:
(1) a / b = q1 ... r1
a = q1 * b + r1 b = b
if: r1 == 0 , gcd(a, b) = b
(2) b / r1 = q2 ... r2
b = q2 * r1 + r2 r1 = r1
if: r2 == 0 , gcd(b, r1) = r1;
a = q1*q2*r1 + r1 b = q2*r1
gcd(a, b) = r1
复杂度: 在O(log max(a, b)) 以内
代码:
int gcd (int a, int b) { return !b ? a : gcd (b, a % b); }
2.扩展欧几里德算法
扩展欧几里德算法是用来在已知 a, b 求解一组 x, y ,使它们满足贝祖等式:
ax + by = gcd(a, b)(解一定存在)。扩展欧几里德常用在求解模线性方程及方程组中。
理解 x 和 y:
已知了 ax + by = gcd(a, b) 一定是有解的 (数论相关定理可证)。
1. 显然当 b = 0,gcd(a, b) = a。 此时 x = 1, y = 0;
2. a > b > 0 时:
设 a x1 + b y1 = gcd (a, b);
b x2 + (a mod b) y2 = gcd (b, a mod b);
根据欧几里德原理 gcd(a, b) = gcd(b, a mod b);
则 a x1 + b y1 = b x2 + (a mod b) y2;
即: a x1 + b y1 = b x2 + (a - [a / b] * b) y2 = a y2 + b x2 - [a/b] * b y2;
(这里说明一下: a mod b = a - [a / b] * b [a / b] 代表取整 )
那么 a x1 + b y1 = a y2 + b (x2 - [a / b] * y2).
结论: x1 = y2; y1 = x2 - [a / b] * y2.
这样就找到了求解x1 , y1 的方法。
代码:
int extgcd (int a, int b, int& x, int& y) { int d = a; if (b != 0) { d = extgcd (b, a % b, y, x); y -= (a/ b) * x; } else { x = 1; y = 0; } return d; }
这里返回的d 就是gcd(a, b) 的值。
关于解 x 和 y 的大小:
事实上,如果 ab ≠ 0 , 可知道 |x| ≤ b 且 |y| ≤ a.
标签:除法,gcd,r2,int,辗转,6.2,y1,y2,r1 来源: https://www.cnblogs.com/astonc/p/10656932.html