扩展欧几里得算法
2017-07-27 18:57
218 查看
扩展欧几里得算法是为了解决这样一个问题:
给定两个非零的整数a和b,求一组正整数(x, y),使得ax+ by = gcd(a, b)成立,其中gcd(a, b)表示a 和b 的最大公约数。
有前面用到的欧几里得算法求最大公约数的方法可知,它总是把gcd(a, b)转化为求解gcd(b, a%b),当b 变为0的时候返回a,此时a 就等于gcd。也就是说欧几里得算法结束的时候变量a 中存放的是gcd,变量b 中存放的是0,因此此时显然有a*1 + b*0 = gcd(a, b)成立,此时有x = 1, y = 0成立。
所以,不妨我们用上面的欧几里得算法的过程来计算x 和y。
当计算gcd(a, b)时,有ax1 + by1 = gcd成立;而在下一步计算gcd(b, a%b)时,又有bx2 + (a%b)y2 = gcd成立。由此ax1 + by1 = bx2 + (a%b)y2成立。有考虑到有关系a%b = a - (a/b)*b成立,因此ax1 + by1 = bx2 + (a - (a/b)*b)y2成立。整理式子之后得到ax1 + by1
= ay2 + b(x2 - (a/b)y2)。
因此,对比等号左右两边可以马上得到下面的推到公式:
x1 = y2
y1 = x2 - (a/b)y2
由此便可以通过x2和y2来反推x1 和y1了。于是只需要到达递归边界、不断退出的过程中根据上面的公式计算x和y,就可以得到一组解。代码如下:
给定两个非零的整数a和b,求一组正整数(x, y),使得ax+ by = gcd(a, b)成立,其中gcd(a, b)表示a 和b 的最大公约数。
有前面用到的欧几里得算法求最大公约数的方法可知,它总是把gcd(a, b)转化为求解gcd(b, a%b),当b 变为0的时候返回a,此时a 就等于gcd。也就是说欧几里得算法结束的时候变量a 中存放的是gcd,变量b 中存放的是0,因此此时显然有a*1 + b*0 = gcd(a, b)成立,此时有x = 1, y = 0成立。
int gcd(int a, int b) { if(b == 0) return a; else return gcd(b, a%b); }
所以,不妨我们用上面的欧几里得算法的过程来计算x 和y。
当计算gcd(a, b)时,有ax1 + by1 = gcd成立;而在下一步计算gcd(b, a%b)时,又有bx2 + (a%b)y2 = gcd成立。由此ax1 + by1 = bx2 + (a%b)y2成立。有考虑到有关系a%b = a - (a/b)*b成立,因此ax1 + by1 = bx2 + (a - (a/b)*b)y2成立。整理式子之后得到ax1 + by1
= ay2 + b(x2 - (a/b)y2)。
因此,对比等号左右两边可以马上得到下面的推到公式:
x1 = y2
y1 = x2 - (a/b)y2
由此便可以通过x2和y2来反推x1 和y1了。于是只需要到达递归边界、不断退出的过程中根据上面的公式计算x和y,就可以得到一组解。代码如下:
int exGcd(int a, int b, int &x, int &y) { if(b == 0) { x = 1; y = 0; return a; } int g = exGcd(b, a%b, x, y); //递归计算exGcd(b,a%b) int temp = x; //存放x的数值 x = y; y = temp - (a/b)*y; return g; }
相关文章推荐
- 欧几里得扩展算法
- 欧几里得算法和扩展欧几里得算法
- 欧几里得扩展算法
- 欧几里得(Euclid)算法及其扩展
- 扩展欧几里得算法理解
- poj 1061 小白算法练习 数论 扩展欧几里得 青蛙的约会
- 欧几里得扩展算法详解及POJ1061
- Java实现算法导论中求解模线性方程解(基于最大公约数欧几里得扩展算法)
- 关于欧几里得及其扩展算法(C语言实现)
- 欧几里得及欧几里得扩展算法
- 欧几里得扩展算法
- 欧几里得扩展算法
- 欧几里得扩展算法
- 算法-扩展欧几里得
- 欧几里得扩展算法
- [数论]HOJ 2185 Min Chain 扩展欧几里得算法
- [省选前题目整理][SGU 261]Discrete Roots(扩展欧几里得+中国剩余定理+原根+大步小步算法)
- 扩展欧几里得(Extended Euclid)算法求最大公约数和乘法逆元
- 扩展欧几里得 小白算法学习
- 欧几里得扩展算法