扩展欧几里德算法主要用来求ax + by = d这样的等式的整数解,当且仅当gcd(a,b) = d时该算法可直接求该等式,当gcd(a,b) != d时,可先求ax + by = gcd(a,b),然后按照进行值统一法,见解求解。
首先统一如下知识
1. a mod b = a - floor(a / b) * b
其实这个等式只是用数学语言描述的很严格,我们以前上小学时就学过了怎么计算除法,除不进就有余数,那是的那种方法其实就是向下取整的求法。
2.其实这个算法要理解并不难,关键是人家怎么想到的,首先我们知道gcd(a,b) == gcd(b, a mod b),也就是说ax + by = gcd(b,a mod b) = .... 直到 a’ mod b‘ == 0即gcd(b’,a' mod b'== 0),此时就代表着系数a = b‘,b = 0,我们就可以直接求出x的值了,于是又可一回代入上层的gcd(a’,b')。
算法分析:
对于b != 0,Extended-Euclid(a,b),先计算d' = gcd(b, a mod b)和d‘ = bx’ + (a mod b)y‘(由ax + by = gcd(a,b)可知),于是有d = d’ = bx‘ + (a - floor(a / b) b)y’ = ay' + b(x' - floor(a/b)y')
所以算法(伪代码)可如下
Extended-Euclid(a,b)
if(b == 0)
return (a,1,0)//gcd(a,0) == a,ax + 0 = a,x == 1
(d',x',y') = Extend-Euclid(b, a mod b)
(d,x,y) = (d',y',x' - floor(a / b)y')
return (d,x,y);
我的C代码实现
#include <stdio.h> void Extend_Eculid(int a,int b,int &d,int &x,int &y){ if(b == 0){ d = a,x = 1,y = 0; }else{ int x1,y1; Extend_Eculid(b, a % b,d,x1,y1); x = y1,y = x1 - (a /b) * y1; } } int main(){ int d,x,y; Extend_Eculid(99,78,d,x,y); printf("%d %d %d",d,x,y); }